@2digits/opencode-plugin 0.2.2 → 0.2.4
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/dist/{index.d.ts → index.d.mts} +4 -1
- package/dist/index.mjs +3 -0
- package/package.json +19 -19
- package/dist/index.js +0 -4
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{PostHog as e}from"posthog-node";import t from"node:path";import{randomUUID as n}from"node:crypto";const r=`@2digits/opencode-plugin`,i=`opencode`,a=/api[-_]?key|token|secret|password|authorization|cookie|session|bearer|x-api-key|credential/i;function o(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function s(e){if(e!=null)try{return JSON.stringify(e)}catch{return}}function c(e,t){if(t<=0)return``;if(e.length<=t)return e;let n=e.length-t;return`${e.slice(0,t)}...[truncated ${n} chars]`}function l(e,t,n){if(n>8)return`[DepthLimit]`;if(typeof e!=`object`||!e)return e;if(t.has(e))return`[Circular]`;if(t.add(e),Array.isArray(e))return e.map(e=>l(e,t,n+1));let r={};for(let[i,o]of Object.entries(e))r[i]=a.test(i)?`[REDACTED]`:l(o,t,n+1);return r}function u(e,t){if(e==null)return;let n=l(e,new WeakSet,0);if(typeof n==`string`)return c(n,t);let r=s(n);return r?c(r,t):void 0}function d(e){return e===`session`?`session`:`message`}function f(e,t){let n=Number.parseInt(e??``,10);return Number.isFinite(n)&&n>0?n:t}function p(e){if(!e)return{};try{let t=JSON.parse(e);return o(t)?t:{}}catch{return{}}}function m(e){if(!e)return!0;try{return o(JSON.parse(e))}catch{return!1}}function h(e){let t=e?.trim();if(t)return t}function g(e){let n=t.basename(e);return n.length>0?n:`opencode-project`}function _(e){if(!e)return;let t=e.replaceAll(/\s+/g,` `).trim();if(t)return t.slice(0,120)}function v(e,t){return e.distinctId??e.gitEmail??t}function y(e,t){return`${e}:${t}`}function b(e,t){return`${e}:${t}`}function x(e,t){if(t)return`error`;if(e)return e===`tool-calls`?`tool_calls`:e}function S(e){if(e){if(o(e)){if(typeof e.message==`string`)return e.message;if(o(e.data)&&typeof e.data.message==`string`)return e.data.message;if(typeof e.name==`string`)return e.name}return s(e)}}function C(e){let t=e.filter(e=>e.type===`text`&&!e.synthetic&&typeof e.text==`string`).map(e=>e.text??``).join(`
|
|
2
|
+
`).trim();return t.length>0?t:void 0}function w(e){if(!e)return;let t=e.order.map(t=>e.parts.get(t)??``).join(`
|
|
3
|
+
`).trim();return t.length>0?t:void 0}function T(e,t){if(!(t||!e))return[{role:`user`,content:e}]}function E(e,t,n){if(!n){if(e)return[{role:`assistant`,content:e}];if(t)return[{role:`assistant`,content:t}]}}function D(e,t,n){return{$ai_trace_id:t.traceID,$ai_session_id:t.sessionID,$ai_latency:n,$ai_input_state:e.privacyMode?void 0:u(t.inputState,e.maxAttributeLength),$ai_output_state:e.privacyMode?void 0:u(t.outputState,e.maxAttributeLength),$ai_total_input_tokens:t.totalInputTokens,$ai_total_output_tokens:t.totalOutputTokens,$ai_total_cost_usd:t.totalCostUsd,$ai_is_error:t.hasError,$ai_error:t.errorMessage,$ai_span_name:t.traceName,$ai_lib:r,$ai_framework:i,$ai_project_name:e.projectName,$ai_agent_name:t.agentName,...e.customProperties}}function O(e){let{config:t,errorMessage:n,generation:a,info:o,output:s,pending:c,toolCallCount:l,toolsCalled:u,traceState:d}=e,f=Math.max(0,o.time.completed-o.time.created)/1e3;return{$ai_trace_id:a.traceID,$ai_session_id:o.sessionID,$ai_span_id:a.spanID,$ai_model:o.modelID,$ai_provider:o.providerID,$ai_input:T(c.prompt,t.privacyMode),$ai_output_choices:E(s,n,t.privacyMode),$ai_user_prompt:t.privacyMode?void 0:c.prompt,$ai_input_tokens:o.tokens.input,$ai_output_tokens:o.tokens.output,$ai_total_tokens:o.tokens.input+o.tokens.output+o.tokens.reasoning+o.tokens.cache.read+o.tokens.cache.write,$ai_latency:f,$ai_total_cost_usd:o.cost,$ai_stop_reason:x(o.finish,!!o.error),$ai_is_error:!!o.error,$ai_error:n,$ai_tools_called:u,$ai_tool_call_count:l,cache_read_input_tokens:o.tokens.cache.read,cache_creation_input_tokens:o.tokens.cache.write,$ai_lib:r,$ai_framework:i,$ai_project_name:t.projectName,$ai_agent_name:d.agentName,...t.customProperties}}function k(e){let{config:t,latency:n,output:a,toolCall:o,toolName:s,traceState:c}=e;return{$ai_trace_id:o.traceID,$ai_session_id:o.sessionID,$ai_span_id:crypto.randomUUID(),$ai_parent_id:o.parentSpanID,$ai_span_name:s,$ai_input_state:t.privacyMode?void 0:u(o.args,t.maxAttributeLength),$ai_output_state:t.privacyMode?void 0:u(a,t.maxAttributeLength),$ai_latency:n,$ai_is_error:!1,$ai_error:void 0,$ai_lib:r,$ai_framework:i,$ai_project_name:t.projectName,$ai_agent_name:c?.agentName??t.projectName,...t.customProperties}}function A(t){let n,i=!1;function a(){if(n)return n;try{return n=new e(t.apiKey,{host:t.host,flushAt:20,flushInterval:1e4}),n}catch(e){console.error(`${r}: failed to initialize PostHog client`,e);return}}function o(e,n,r){let i=a();i&&i.capture({distinctId:v(t,n),event:e,properties:r})}async function s(e,n,r){let i=a();i&&await i.captureImmediate({distinctId:v(t,n),event:e,properties:r})}async function c(){n&&=(await n.shutdown(),void 0)}function l(e){i||(i=!0,process.once(`beforeExit`,()=>{e()}),process.once(`SIGINT`,()=>{e()}),process.once(`SIGTERM`,()=>{e()}))}return{capture:o,captureImmediate:s,registerShutdown:l,shutdown:c}}async function j(e){try{return h(await e.$`git config --get user.email`.text())}catch{return}}async function M(e){let t=g(e.worktree||e.directory),n=p(process.env.POSTHOG_LLMA_CUSTOM_PROPERTIES);return m(process.env.POSTHOG_LLMA_CUSTOM_PROPERTIES)||console.warn(`${r}: ignoring invalid POSTHOG_LLMA_CUSTOM_PROPERTIES JSON`),{apiKey:process.env.POSTHOG_OPENCODE_API_KEY??`phc_qAbssQWcjrSz9NutSQsNrWWpQqLsTGo7ZnHchwa5C6Tb`,host:process.env.POSTHOG_OPENCODE_HOST??`https://eu.i.posthog.com`,enabled:process.env.POSTHOG_OPENCODE_ENABLED!==`false`,privacyMode:process.env.POSTHOG_OPENCODE_LLMA_PRIVACY_MODE===`true`,traceGrouping:d(process.env.POSTHOG_OPENCODE_LLMA_TRACE_GROUPING),sessionWindowMinutes:f(process.env.POSTHOG_OPENCODE_LLMA_SESSION_WINDOW_MINUTES,60),maxAttributeLength:f(process.env.POSTHOG_OPENCODE_MAX_ATTRIBUTE_LENGTH,12e3),distinctId:h(process.env.POSTHOG_OPENCODE_LLMA_DISTINCT_ID),gitEmail:await j(e),projectName:t,customProperties:n}}function N(e){let t=new Map,r=new Map,i=new Map,a=new Map,o=new Map,s=new Map,c=new Map,l=new Map,u=new Set;function d(e){i.delete(e),r.delete(e),l.delete(e);for(let[n,r]of t.entries())r.sessionID===e&&t.delete(n);let n=new Set;for(let[t,r]of c.entries())r.sessionID===e&&(n.add(r.spanID),c.delete(t),s.delete(t),u.delete(t));for(let e of n)o.delete(e);for(let[t,n]of a.entries())n.sessionID===e&&a.delete(t)}function f(e){return i.get(e)}function p(){return[...i.keys()]}function m(t,r,a){let o=i.get(t)??{agentName:r??e.projectName,errorMessage:void 0,hasError:!1,inputState:void 0,lastActivityAt:a,lastTraceCapturedAt:void 0,outputState:void 0,sessionID:t,startedAt:a,totalCostUsd:0,totalInputTokens:0,totalOutputTokens:0,traceID:n(),traceName:void 0};return o.agentName=r??o.agentName,o.lastActivityAt=a,i.set(t,o),o}function h(i,a){let o=Date.now(),s=m(i.sessionID,i.agent,o),c=C(a.parts),u={agentName:i.agent??e.projectName,prompt:c,sessionID:i.sessionID,traceID:s.traceID,spanID:n(),startedAt:o,userMessageID:a.message.id};s.inputState??=c,s.traceName??=_(c),t.set(y(i.sessionID,a.message.id),u),r.set(i.sessionID,u),l.delete(i.sessionID)}function g(e){let t=s.get(e.messageID)??{order:[],parts:new Map};t.parts.has(e.id)||t.order.push(e.id),t.parts.set(e.id,e.text),s.set(e.messageID,t)}function v(e){return w(s.get(e))}function x(e,t){let n=i.get(e);n&&(n.hasError=!0,n.errorMessage=S(t),n.lastActivityAt=Date.now())}function T(e){let n=y(e.sessionID,e.parentID),a=t.get(n)??r.get(e.sessionID),o=i.get(e.sessionID);if(!(!a||!o))return{pending:a,pendingKey:n,traceState:o}}function E(e){let t=T(e);if(!t)return;let r=c.get(e.id);if(r)return{generation:r,...t};let i=l.get(e.sessionID),a=i&&i!==e.id?n():t.pending.spanID,o={assistantMessageID:e.id,pendingKey:t.pendingKey,sessionID:e.sessionID,spanID:a,traceID:t.pending.traceID};return t.pending.spanID=a,c.set(e.id,o),l.set(e.sessionID,e.id),{generation:o,...t}}function D(e,t,n){e.agentName=n.mode||t.agentName,e.lastActivityAt=n.time.completed,e.totalCostUsd+=n.cost,e.totalInputTokens+=n.tokens.input,e.totalOutputTokens+=n.tokens.output;let r=S(n.error);return e.outputState=n.output??r??e.outputState,r&&(e.hasError=!0,e.errorMessage=r),r}function O(e){return u.has(e)}function k(e){u.add(e)}function A(e,t){s.delete(e),o.delete(t)}function j(e){return r.get(e)}function M(e,t,n){a.set(b(e,t),n)}function N(e,t){let n=b(e,t),r=a.get(n);if(r)return a.delete(n),r}function P(e,t){let n=o.get(e)??[];n.push(t),o.set(e,n)}function F(e){let t=o.get(e);return!t||t.length===0?{}:{toolsCalled:[...new Set(t)],toolCallCount:t.length}}function I(e){return e.role===`assistant`&&!!e.time.completed&&!u.has(e.id)}return{beginPrompt:h,clearSessionState:d,cleanupAssistantMessage:A,getActiveMessage:j,getAssistantOutputForMessage:v,getGenerationToolProperties:F,getOrCreateGenerationState:E,getTraceState:f,getTraceSessionIDs:p,getOrCreateTraceState:m,hasCompletedAssistantMessage:O,markAssistantMessageCompleted:k,markSessionError:x,recordGenerationToolCall:P,setToolCall:M,shouldCompleteAssistantMessage:I,storeAssistantOutput:g,takeToolCall:N,updateTraceStateFromAssistantMessage:D}}const P=async e=>{let t=await M(e);if(!t.enabled)return{};if(!t.apiKey)return console.warn(`${r}: missing POSTHOG_API_KEY, analytics disabled`),{};let n=N(t),i=A(t);async function a(e){if(e.lastTraceCapturedAt===e.lastActivityAt)return;let n=Math.max(0,e.lastActivityAt-e.startedAt)/1e3;await i.captureImmediate(`$ai_trace`,e.sessionID,D(t,e,n)),e.lastTraceCapturedAt=e.lastActivityAt}async function o(e){let t=n.getTraceState(e);t&&(await a(t),n.clearSessionState(e))}async function s(){for(let e of n.getTraceSessionIDs())await o(e);await i.shutdown()}i.registerShutdown(s);async function c(e){let r=n.getOrCreateGenerationState(e);if(!r)return;let{generation:o,pending:s,traceState:c}=r,l=n.getAssistantOutputForMessage(e.id),u=n.updateTraceStateFromAssistantMessage(c,s,{mode:e.mode,time:{completed:e.time.completed},cost:e.cost,tokens:{input:e.tokens.input,output:e.tokens.output},output:l,error:e.error}),{toolsCalled:d,toolCallCount:f}=n.getGenerationToolProperties(o.spanID);i.capture(`$ai_generation`,e.sessionID,O({config:t,pending:s,generation:o,traceState:c,info:e,errorMessage:u,output:l,toolsCalled:d,toolCallCount:f})),await a(c),n.cleanupAssistantMessage(e.id,o.spanID)}async function l(e){if(e.type===`message.part.updated`){let{part:t}=e.properties;t.type===`text`&&n.storeAssistantOutput(t);return}if(e.type===`session.deleted`){await o(e.properties.info.id);return}if(e.type===`session.error`){let{error:t,sessionID:r}=e.properties;r&&n.markSessionError(r,t);return}if(e.type!==`message.updated`)return;let{info:t}=e.properties;t.role===`assistant`&&(n.getOrCreateGenerationState(t),n.shouldCompleteAssistantMessage(t)&&(n.markAssistantMessageCompleted(t.id),await c(t)))}return{"chat.message":async(e,r)=>{let i=Date.now(),a=n.getTraceState(e.sessionID),s=t.sessionWindowMinutes*6e4;a&&t.traceGrouping===`message`&&await o(e.sessionID),a&&t.traceGrouping===`session`&&i-a.lastActivityAt>=s&&await o(e.sessionID),n.beginPrompt(e,r)},"tool.execute.before":(e,t)=>{let r=n.getActiveMessage(e.sessionID);return r?(n.setToolCall(e.sessionID,e.callID,{args:t.args,parentSpanID:r.spanID,sessionID:e.sessionID,startedAt:Date.now(),traceID:r.traceID}),n.recordGenerationToolCall(r.spanID,e.tool),Promise.resolve()):Promise.resolve()},"tool.execute.after":async(e,r)=>{let a=n.takeToolCall(e.sessionID,e.callID);if(!a)return;let o=n.getTraceState(a.sessionID);o&&(o.lastActivityAt=Date.now()),i.capture(`$ai_span`,a.sessionID,k({config:t,toolCall:a,traceState:o,toolName:e.tool,output:r,latency:Math.max(0,Date.now()-a.startedAt)/1e3}))},event:async({event:e})=>l(e)}};export{P as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2digits/opencode-plugin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "OpenCode plugin for PostHog LLM analytics integration",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -13,40 +13,40 @@
|
|
|
13
13
|
],
|
|
14
14
|
"type": "module",
|
|
15
15
|
"sideEffects": false,
|
|
16
|
-
"main": "./dist/index.
|
|
17
|
-
"module": "./dist/index.
|
|
18
|
-
"types": "./dist/index.d.
|
|
16
|
+
"main": "./dist/index.mjs",
|
|
17
|
+
"module": "./dist/index.mjs",
|
|
18
|
+
"types": "./dist/index.d.mts",
|
|
19
19
|
"exports": {
|
|
20
20
|
".": {
|
|
21
21
|
"import": {
|
|
22
|
-
"types": "./dist/index.d.
|
|
23
|
-
"default": "./dist/index.
|
|
22
|
+
"types": "./dist/index.d.mts",
|
|
23
|
+
"default": "./dist/index.mjs"
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
|
+
"./package.json": "./package.json",
|
|
26
27
|
"./server": {
|
|
27
28
|
"import": {
|
|
28
|
-
"types": "./dist/index.d.
|
|
29
|
-
"default": "./dist/index.
|
|
29
|
+
"types": "./dist/index.d.mts",
|
|
30
|
+
"default": "./dist/index.mjs"
|
|
30
31
|
}
|
|
31
|
-
}
|
|
32
|
-
"./package.json": "./package.json"
|
|
32
|
+
}
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@opencode-ai/plugin": "1.14.
|
|
36
|
-
"posthog-node": "5.30.
|
|
35
|
+
"@opencode-ai/plugin": "1.14.29",
|
|
36
|
+
"posthog-node": "5.30.8"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@
|
|
40
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
41
|
-
"
|
|
39
|
+
"@arethetypeswrong/core": "0.18.2",
|
|
40
|
+
"@typescript/native-preview": "7.0.0-dev.20260429.1",
|
|
41
|
+
"publint": "0.3.18",
|
|
42
42
|
"typescript": "6.0.3",
|
|
43
|
-
"vite-plus": "0.1.
|
|
44
|
-
"vitest": "npm:@voidzero-dev/vite-plus-test@0.1.
|
|
43
|
+
"vite-plus": "0.1.20",
|
|
44
|
+
"vitest": "npm:@voidzero-dev/vite-plus-test@0.1.20",
|
|
45
45
|
"@2digits/tsconfig": "0.8.7"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
|
-
"build": "
|
|
49
|
-
"dev": "
|
|
48
|
+
"build": "vp pack --minify --config-loader unconfig",
|
|
49
|
+
"dev": "vp pack --watch --config-loader unconfig",
|
|
50
50
|
"test": "vp test run",
|
|
51
51
|
"types": "tsgo --noEmit"
|
|
52
52
|
}
|
package/dist/index.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{PostHog as Pe}from"posthog-node";var G="https://eu.i.posthog.com",R=12000,L=60,g="@2digits/opencode-plugin",O="opencode",I=/api[-_]?key|token|secret|password|authorization|cookie|session|bearer|x-api-key|credential/i;import ge from"path";function $(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function j(e){if(e===void 0||e===null)return;try{return JSON.stringify(e)}catch{return}}function H(e,t){if(t<=0)return"";if(e.length<=t)return e;let r=e.length-t;return`${e.slice(0,t)}...[truncated ${r} chars]`}function N(e,t,r){if(r>8)return"[DepthLimit]";if(e===null||e===void 0)return e;if(typeof e!=="object")return e;if(t.has(e))return"[Circular]";if(t.add(e),Array.isArray(e))return e.map((u)=>N(u,t,r+1));let p={};for(let[u,f]of Object.entries(e))p[u]=I.test(u)?"[REDACTED]":N(f,t,r+1);return p}function C(e,t){if(e===void 0||e===null)return;let r=N(e,new WeakSet,0);if(typeof r==="string")return H(r,t);let p=j(r);return p?H(p,t):void 0}function U(e){return e==="session"?"session":"message"}function k(e,t){let r=Number.parseInt(e??"",10);return Number.isFinite(r)&&r>0?r:t}function W(e){if(!e)return{};try{let t=JSON.parse(e);return $(t)?t:{}}catch{return{}}}function v(e){if(!e)return!0;try{return $(JSON.parse(e))}catch{return!1}}function w(e){let t=e?.trim();if(!t)return;return t}function B(e){let t=ge.basename(e);return t.length>0?t:"opencode-project"}function F(e){if(!e)return;let t=e.replaceAll(/\s+/g," ").trim();if(!t)return;return t.slice(0,120)}function D(e,t){return e.distinctId??e.gitEmail??t}function M(e,t){return`${e}:${t}`}function h(e,t){return`${e}:${t}`}function J(e,t){if(t)return"error";if(!e)return;if(e==="tool-calls")return"tool_calls";return e}function x(e){if(!e)return;if($(e)){if(typeof e.message==="string")return e.message;if($(e.data)&&typeof e.data.message==="string")return e.data.message;if(typeof e.name==="string")return e.name}return j(e)}function z(e){let t=e.filter((r)=>r.type==="text"&&!r.synthetic&&typeof r.text==="string").map((r)=>r.text??"").join(`
|
|
3
|
-
`).trim();return t.length>0?t:void 0}function K(e){if(!e)return;let t=e.order.map((r)=>e.parts.get(r)??"").join(`
|
|
4
|
-
`).trim();return t.length>0?t:void 0}function V(e,t){if(t||!e)return;return[{role:"user",content:e}]}function Y(e,t,r){if(r)return;if(e)return[{role:"assistant",content:e}];if(t)return[{role:"assistant",content:t}];return}function Q(e,t,r){return{$ai_trace_id:t.traceID,$ai_session_id:t.sessionID,$ai_latency:r,$ai_total_input_tokens:t.totalInputTokens,$ai_total_output_tokens:t.totalOutputTokens,$ai_is_error:t.hasError,$ai_error:t.errorMessage,$ai_span_name:t.traceName,$ai_lib:g,$ai_framework:O,$ai_project_name:e.projectName,$ai_agent_name:t.agentName,...e.customProperties}}function X(e){let{config:t,errorMessage:r,generation:p,info:u,output:f,pending:m,toolCallCount:_,toolsCalled:i,traceState:c}=e,a=Math.max(0,u.time.completed-u.time.created)/1000;return{$ai_trace_id:p.traceID,$ai_session_id:u.sessionID,$ai_span_id:p.spanID,$ai_model:u.modelID,$ai_provider:u.providerID,$ai_input:V(m.prompt,t.privacyMode),$ai_output_choices:Y(f,r,t.privacyMode),$ai_user_prompt:t.privacyMode?void 0:m.prompt,$ai_input_tokens:u.tokens.input,$ai_output_tokens:u.tokens.output,$ai_total_tokens:u.tokens.input+u.tokens.output+u.tokens.reasoning+u.tokens.cache.read+u.tokens.cache.write,$ai_latency:a,$ai_total_cost_usd:u.cost,$ai_stop_reason:J(u.finish,Boolean(u.error)),$ai_is_error:Boolean(u.error),$ai_error:r,$ai_tools_called:i,$ai_tool_call_count:_,cache_read_input_tokens:u.tokens.cache.read,cache_creation_input_tokens:u.tokens.cache.write,$ai_lib:g,$ai_framework:O,$ai_project_name:t.projectName,$ai_agent_name:c.agentName,...t.customProperties}}function q(e){let{config:t,latency:r,output:p,toolCall:u,toolName:f,traceState:m}=e;return{$ai_trace_id:u.traceID,$ai_session_id:u.sessionID,$ai_span_id:crypto.randomUUID(),$ai_parent_id:u.parentSpanID,$ai_span_name:f,$ai_input_state:t.privacyMode?void 0:C(u.args,t.maxAttributeLength),$ai_output_state:t.privacyMode?void 0:C(p,t.maxAttributeLength),$ai_latency:r,$ai_is_error:!1,$ai_error:void 0,$ai_lib:g,$ai_framework:O,$ai_project_name:t.projectName,$ai_agent_name:m?.agentName??t.projectName,...t.customProperties}}function Z(e){let t,r=!1;function p(){if(t)return t;try{return t=new Pe(e.apiKey,{host:e.host,flushAt:20,flushInterval:1e4}),t}catch(_){console.error(`${g}: failed to initialize PostHog client`,_);return}}function u(_,i,c){let a=p();if(!a)return;a.capture({distinctId:D(e,i),event:_,properties:c})}async function f(){if(!t)return;await t.shutdown(),t=void 0}function m(_){if(r)return;r=!0,process.once("beforeExit",()=>{_()}),process.once("SIGINT",()=>{_()}),process.once("SIGTERM",()=>{_()})}return{capture:u,registerShutdown:m,shutdown:f}}async function Te(e){try{return w(await e.$`git config --get user.email`.text())}catch{return}}async function ee(e){let t=B(e.worktree||e.directory),r=W(process.env.POSTHOG_LLMA_CUSTOM_PROPERTIES);if(!v(process.env.POSTHOG_LLMA_CUSTOM_PROPERTIES))console.warn(`${g}: ignoring invalid POSTHOG_LLMA_CUSTOM_PROPERTIES JSON`);return{apiKey:process.env.POSTHOG_OPENCODE_API_KEY??"phc_qAbssQWcjrSz9NutSQsNrWWpQqLsTGo7ZnHchwa5C6Tb",host:process.env.POSTHOG_OPENCODE_HOST??G,enabled:process.env.POSTHOG_OPENCODE_ENABLED!=="false",privacyMode:process.env.POSTHOG_OPENCODE_LLMA_PRIVACY_MODE==="true",traceGrouping:U(process.env.POSTHOG_OPENCODE_LLMA_TRACE_GROUPING),sessionWindowMinutes:k(process.env.POSTHOG_OPENCODE_LLMA_SESSION_WINDOW_MINUTES,L),maxAttributeLength:k(process.env.POSTHOG_OPENCODE_MAX_ATTRIBUTE_LENGTH,R),distinctId:w(process.env.POSTHOG_OPENCODE_LLMA_DISTINCT_ID),gitEmail:await Te(e),projectName:t,customProperties:r}}import{randomUUID as S}from"crypto";function te(e){let t=new Map,r=new Map,p=new Map,u=new Map,f=new Map,m=new Map,_=new Map,i=new Map,c=new Set;function a(n){p.delete(n),r.delete(n),i.delete(n);for(let[s,d]of t.entries())if(d.sessionID===n)t.delete(s);let o=new Set;for(let[s,d]of _.entries()){if(d.sessionID!==n)continue;o.add(d.spanID),_.delete(s),m.delete(s),c.delete(s)}for(let s of o)f.delete(s);for(let[s,d]of u.entries())if(d.sessionID===n)u.delete(s)}function l(n){return p.get(n)}function P(){return[...p.keys()]}function E(n,o,s){let d=p.get(n)??{agentName:o??e.projectName,errorMessage:void 0,hasError:!1,lastActivityAt:s,sessionID:n,startedAt:s,totalCostUsd:0,totalInputTokens:0,totalOutputTokens:0,traceID:S(),traceName:void 0};return d.agentName=o??d.agentName,d.lastActivityAt=s,p.set(n,d),d}function A(n,o){let s=Date.now(),d=E(n.sessionID,n.agent,s),T=z(o.parts),y={agentName:n.agent??e.projectName,prompt:T,sessionID:n.sessionID,traceID:d.traceID,spanID:S(),startedAt:s,userMessageID:o.message.id};d.traceName??=F(T),t.set(M(n.sessionID,o.message.id),y),r.set(n.sessionID,y),i.delete(n.sessionID)}function b(n){let o=m.get(n.messageID)??{order:[],parts:new Map};if(!o.parts.has(n.id))o.order.push(n.id);o.parts.set(n.id,n.text),m.set(n.messageID,o)}function ne(n){return K(m.get(n))}function re(n,o){let s=p.get(n);if(!s)return;s.hasError=!0,s.errorMessage=x(o),s.lastActivityAt=Date.now()}function ie(n){let o=M(n.sessionID,n.parentID),s=t.get(o)??r.get(n.sessionID),d=p.get(n.sessionID);if(!s||!d)return;return{pending:s,pendingKey:o,traceState:d}}function oe(n){let o=ie(n);if(!o)return;let s=_.get(n.id);if(s)return{generation:s,...o};let d=i.get(n.sessionID),T=d&&d!==n.id?S():o.pending.spanID,y={assistantMessageID:n.id,pendingKey:o.pendingKey,sessionID:n.sessionID,spanID:T,traceID:o.pending.traceID};return o.pending.spanID=T,_.set(n.id,y),i.set(n.sessionID,n.id),{generation:y,...o}}function se(n,o,s){n.agentName=s.mode||o.agentName,n.lastActivityAt=s.time.completed,n.totalCostUsd+=s.cost,n.totalInputTokens+=s.tokens.input,n.totalOutputTokens+=s.tokens.output;let d=x(s.error);if(d)n.hasError=!0,n.errorMessage=d;return d}function ue(n){return c.has(n)}function ae(n){c.add(n)}function ce(n,o){m.delete(n),f.delete(o)}function de(n){return r.get(n)}function pe(n,o,s){u.set(h(n,o),s)}function _e(n,o){let s=h(n,o),d=u.get(s);if(!d)return;return u.delete(s),d}function fe(n,o){let s=f.get(n)??[];s.push(o),f.set(n,s)}function le(n){let o=f.get(n);if(!o||o.length===0)return{};return{toolsCalled:[...new Set(o)],toolCallCount:o.length}}function me(n){return n.role==="assistant"&&Boolean(n.time.completed)&&!c.has(n.id)}return{beginPrompt:A,clearSessionState:a,cleanupAssistantMessage:ce,getActiveMessage:de,getAssistantOutputForMessage:ne,getGenerationToolProperties:le,getOrCreateGenerationState:oe,getTraceState:l,getTraceSessionIDs:P,getOrCreateTraceState:E,hasCompletedAssistantMessage:ue,markAssistantMessageCompleted:ae,markSessionError:re,recordGenerationToolCall:fe,setToolCall:pe,shouldCompleteAssistantMessage:me,storeAssistantOutput:b,takeToolCall:_e,updateTraceStateFromAssistantMessage:se}}var ye=async(e)=>{let t=await ee(e);if(!t.enabled)return{};if(!t.apiKey)return console.warn(`${g}: missing POSTHOG_API_KEY, analytics disabled`),{};let r=te(t),p=Z(t);function u(i){let c=r.getTraceState(i);if(!c)return;let a=Math.max(0,c.lastActivityAt-c.startedAt)/1000;p.capture("$ai_trace",c.sessionID,Q(t,c,a)),r.clearSessionState(i)}async function f(){for(let i of r.getTraceSessionIDs())u(i);await p.shutdown()}p.registerShutdown(f);function m(i){let c=r.getOrCreateGenerationState(i);if(!c)return;let{generation:a,pending:l,traceState:P}=c,E=r.updateTraceStateFromAssistantMessage(P,l,{mode:i.mode,time:{completed:i.time.completed},cost:i.cost,tokens:{input:i.tokens.input,output:i.tokens.output},error:i.error}),{toolsCalled:A,toolCallCount:b}=r.getGenerationToolProperties(a.spanID);p.capture("$ai_generation",i.sessionID,X({config:t,pending:l,generation:a,traceState:P,info:i,errorMessage:E,output:r.getAssistantOutputForMessage(i.id),toolsCalled:A,toolCallCount:b})),r.cleanupAssistantMessage(i.id,a.spanID)}async function _(i){if(i.type==="message.part.updated"){let{part:a}=i.properties;if(a.type==="text")r.storeAssistantOutput(a);return}if(i.type==="session.deleted"){u(i.properties.info.id);return}if(i.type==="session.error"){let{error:a,sessionID:l}=i.properties;if(l)r.markSessionError(l,a);return}if(i.type!=="message.updated")return;let{info:c}=i.properties;if(c.role!=="assistant")return;if(r.getOrCreateGenerationState(c),r.shouldCompleteAssistantMessage(c))r.markAssistantMessageCompleted(c.id),m(c)}return{"chat.message":async(i,c)=>{let a=Date.now(),l=r.getTraceState(i.sessionID),P=t.sessionWindowMinutes*60000;if(l&&t.traceGrouping==="message")u(i.sessionID);if(l&&t.traceGrouping==="session"&&a-l.lastActivityAt>=P)u(i.sessionID);r.beginPrompt(i,c)},"tool.execute.before":(i,c)=>{let a=r.getActiveMessage(i.sessionID);if(!a)return Promise.resolve();return r.setToolCall(i.sessionID,i.callID,{args:c.args,parentSpanID:a.spanID,sessionID:i.sessionID,startedAt:Date.now(),traceID:a.traceID}),r.recordGenerationToolCall(a.spanID,i.tool),Promise.resolve()},"tool.execute.after":async(i,c)=>{let a=r.takeToolCall(i.sessionID,i.callID);if(!a)return;let l=r.getTraceState(a.sessionID);if(l)l.lastActivityAt=Date.now();p.capture("$ai_span",a.sessionID,q({config:t,toolCall:a,traceState:l,toolName:i.tool,output:c,latency:Math.max(0,Date.now()-a.startedAt)/1000}))},event:async({event:i})=>_(i)}},Ue=ye;export{Ue as default};
|