@posthog/ai 5.0.1 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -1
- package/lib/anthropic/index.cjs +4 -4
- package/lib/anthropic/index.cjs.map +1 -1
- package/lib/anthropic/index.mjs +4 -4
- package/lib/anthropic/index.mjs.map +1 -1
- package/lib/gemini/index.cjs +364 -0
- package/lib/gemini/index.cjs.map +1 -0
- package/lib/gemini/index.d.ts +60 -0
- package/lib/gemini/index.mjs +357 -0
- package/lib/gemini/index.mjs.map +1 -0
- package/lib/index.cjs +445 -39
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +23 -11
- package/lib/index.mjs +445 -39
- package/lib/index.mjs.map +1 -1
- package/lib/langchain/index.cjs.map +1 -1
- package/lib/langchain/index.mjs.map +1 -1
- package/lib/openai/index.cjs +226 -4
- package/lib/openai/index.cjs.map +1 -1
- package/lib/openai/index.d.ts +16 -4
- package/lib/openai/index.mjs +226 -5
- package/lib/openai/index.mjs.map +1 -1
- package/lib/vercel/index.cjs +5 -5
- package/lib/vercel/index.cjs.map +1 -1
- package/lib/vercel/index.mjs +5 -5
- package/lib/vercel/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/anthropic/index.ts +4 -4
- package/src/gemini/index.ts +4 -4
- package/src/openai/azure.ts +287 -33
- package/src/openai/index.ts +280 -6
- package/src/utils.ts +3 -2
- package/src/vercel/middleware.ts +7 -7
- package/tests/gemini.test.ts +31 -0
- package/tests/openai.test.ts +124 -48
package/src/openai/index.ts
CHANGED
|
@@ -2,14 +2,18 @@ import OpenAIOrignal, { ClientOptions } from 'openai'
|
|
|
2
2
|
import { PostHog } from 'posthog-node'
|
|
3
3
|
import { v4 as uuidv4 } from 'uuid'
|
|
4
4
|
import { formatResponseOpenAI, MonitoringParams, sendEventToPosthog } from '../utils'
|
|
5
|
+
import type { APIPromise } from 'openai'
|
|
6
|
+
import type { Stream } from 'openai/streaming'
|
|
7
|
+
import type { ParsedResponse } from 'openai/resources/responses/responses'
|
|
5
8
|
|
|
6
9
|
type ChatCompletion = OpenAIOrignal.ChatCompletion
|
|
7
10
|
type ChatCompletionChunk = OpenAIOrignal.ChatCompletionChunk
|
|
8
11
|
type ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams
|
|
9
12
|
type ChatCompletionCreateParamsNonStreaming = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParamsNonStreaming
|
|
10
13
|
type ChatCompletionCreateParamsStreaming = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParamsStreaming
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
type ResponsesCreateParamsBase = OpenAIOrignal.Responses.ResponseCreateParams
|
|
15
|
+
type ResponsesCreateParamsNonStreaming = OpenAIOrignal.Responses.ResponseCreateParamsNonStreaming
|
|
16
|
+
type ResponsesCreateParamsStreaming = OpenAIOrignal.Responses.ResponseCreateParamsStreaming
|
|
13
17
|
|
|
14
18
|
interface MonitoringOpenAIConfig extends ClientOptions {
|
|
15
19
|
apiKey: string
|
|
@@ -17,15 +21,19 @@ interface MonitoringOpenAIConfig extends ClientOptions {
|
|
|
17
21
|
baseURL?: string
|
|
18
22
|
}
|
|
19
23
|
|
|
24
|
+
type RequestOptions = Record<string, any>
|
|
25
|
+
|
|
20
26
|
export class PostHogOpenAI extends OpenAIOrignal {
|
|
21
27
|
private readonly phClient: PostHog
|
|
22
28
|
public chat: WrappedChat
|
|
29
|
+
public responses: WrappedResponses
|
|
23
30
|
|
|
24
31
|
constructor(config: MonitoringOpenAIConfig) {
|
|
25
32
|
const { posthog, ...openAIConfig } = config
|
|
26
33
|
super(openAIConfig)
|
|
27
34
|
this.phClient = posthog
|
|
28
35
|
this.chat = new WrappedChat(this, this.phClient)
|
|
36
|
+
this.responses = new WrappedResponses(this, this.phClient)
|
|
29
37
|
}
|
|
30
38
|
}
|
|
31
39
|
|
|
@@ -118,7 +126,7 @@ export class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
118
126
|
const latency = (Date.now() - startTime) / 1000
|
|
119
127
|
await sendEventToPosthog({
|
|
120
128
|
client: this.phClient,
|
|
121
|
-
distinctId: posthogDistinctId
|
|
129
|
+
distinctId: posthogDistinctId,
|
|
122
130
|
traceId,
|
|
123
131
|
model: openAIParams.model,
|
|
124
132
|
provider: 'openai',
|
|
@@ -134,7 +142,7 @@ export class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
134
142
|
} catch (error: any) {
|
|
135
143
|
await sendEventToPosthog({
|
|
136
144
|
client: this.phClient,
|
|
137
|
-
distinctId: posthogDistinctId
|
|
145
|
+
distinctId: posthogDistinctId,
|
|
138
146
|
traceId,
|
|
139
147
|
model: openAIParams.model,
|
|
140
148
|
provider: 'openai',
|
|
@@ -164,7 +172,7 @@ export class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
164
172
|
const latency = (Date.now() - startTime) / 1000
|
|
165
173
|
await sendEventToPosthog({
|
|
166
174
|
client: this.phClient,
|
|
167
|
-
distinctId: posthogDistinctId
|
|
175
|
+
distinctId: posthogDistinctId,
|
|
168
176
|
traceId,
|
|
169
177
|
model: openAIParams.model,
|
|
170
178
|
provider: 'openai',
|
|
@@ -188,7 +196,7 @@ export class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
188
196
|
async (error: any) => {
|
|
189
197
|
await sendEventToPosthog({
|
|
190
198
|
client: this.phClient,
|
|
191
|
-
distinctId: posthogDistinctId
|
|
199
|
+
distinctId: posthogDistinctId,
|
|
192
200
|
traceId,
|
|
193
201
|
model: openAIParams.model,
|
|
194
202
|
provider: 'openai',
|
|
@@ -215,6 +223,272 @@ export class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
215
223
|
}
|
|
216
224
|
}
|
|
217
225
|
|
|
226
|
+
export class WrappedResponses extends OpenAIOrignal.Responses {
|
|
227
|
+
private readonly phClient: PostHog
|
|
228
|
+
|
|
229
|
+
constructor(client: OpenAIOrignal, phClient: PostHog) {
|
|
230
|
+
super(client)
|
|
231
|
+
this.phClient = phClient
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// --- Overload #1: Non-streaming
|
|
235
|
+
public create(
|
|
236
|
+
body: ResponsesCreateParamsNonStreaming & MonitoringParams,
|
|
237
|
+
options?: RequestOptions
|
|
238
|
+
): APIPromise<OpenAIOrignal.Responses.Response>
|
|
239
|
+
|
|
240
|
+
// --- Overload #2: Streaming
|
|
241
|
+
public create(
|
|
242
|
+
body: ResponsesCreateParamsStreaming & MonitoringParams,
|
|
243
|
+
options?: RequestOptions
|
|
244
|
+
): APIPromise<Stream<OpenAIOrignal.Responses.ResponseStreamEvent>>
|
|
245
|
+
|
|
246
|
+
// --- Overload #3: Generic base
|
|
247
|
+
public create(
|
|
248
|
+
body: ResponsesCreateParamsBase & MonitoringParams,
|
|
249
|
+
options?: RequestOptions
|
|
250
|
+
): APIPromise<OpenAIOrignal.Responses.Response | Stream<OpenAIOrignal.Responses.ResponseStreamEvent>>
|
|
251
|
+
|
|
252
|
+
// --- Implementation Signature
|
|
253
|
+
public create(
|
|
254
|
+
body: ResponsesCreateParamsBase & MonitoringParams,
|
|
255
|
+
options?: RequestOptions
|
|
256
|
+
): APIPromise<OpenAIOrignal.Responses.Response | Stream<OpenAIOrignal.Responses.ResponseStreamEvent>> {
|
|
257
|
+
const {
|
|
258
|
+
posthogDistinctId,
|
|
259
|
+
posthogTraceId,
|
|
260
|
+
posthogProperties,
|
|
261
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
262
|
+
posthogPrivacyMode = false,
|
|
263
|
+
posthogGroups,
|
|
264
|
+
posthogCaptureImmediate,
|
|
265
|
+
...openAIParams
|
|
266
|
+
} = body
|
|
267
|
+
|
|
268
|
+
const traceId = posthogTraceId ?? uuidv4()
|
|
269
|
+
const startTime = Date.now()
|
|
270
|
+
|
|
271
|
+
const parentPromise = super.create(openAIParams, options)
|
|
272
|
+
|
|
273
|
+
if (openAIParams.stream) {
|
|
274
|
+
return parentPromise.then((value) => {
|
|
275
|
+
if ('tee' in value && typeof (value as any).tee === 'function') {
|
|
276
|
+
const [stream1, stream2] = (value as any).tee()
|
|
277
|
+
;(async () => {
|
|
278
|
+
try {
|
|
279
|
+
let finalContent: any[] = []
|
|
280
|
+
let usage: {
|
|
281
|
+
inputTokens?: number
|
|
282
|
+
outputTokens?: number
|
|
283
|
+
reasoningTokens?: number
|
|
284
|
+
cacheReadInputTokens?: number
|
|
285
|
+
} = {
|
|
286
|
+
inputTokens: 0,
|
|
287
|
+
outputTokens: 0,
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
for await (const chunk of stream1) {
|
|
291
|
+
if (
|
|
292
|
+
chunk.type === 'response.completed' &&
|
|
293
|
+
'response' in chunk &&
|
|
294
|
+
chunk.response?.output &&
|
|
295
|
+
chunk.response.output.length > 0
|
|
296
|
+
) {
|
|
297
|
+
finalContent = chunk.response.output
|
|
298
|
+
}
|
|
299
|
+
if ('response' in chunk && chunk.response?.usage) {
|
|
300
|
+
usage = {
|
|
301
|
+
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
302
|
+
outputTokens: chunk.response.usage.output_tokens ?? 0,
|
|
303
|
+
reasoningTokens: chunk.response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
304
|
+
cacheReadInputTokens: chunk.response.usage.input_tokens_details?.cached_tokens ?? 0,
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const latency = (Date.now() - startTime) / 1000
|
|
310
|
+
await sendEventToPosthog({
|
|
311
|
+
client: this.phClient,
|
|
312
|
+
distinctId: posthogDistinctId,
|
|
313
|
+
traceId,
|
|
314
|
+
model: openAIParams.model,
|
|
315
|
+
provider: 'openai',
|
|
316
|
+
input: openAIParams.input,
|
|
317
|
+
output: finalContent,
|
|
318
|
+
latency,
|
|
319
|
+
baseURL: (this as any).baseURL ?? '',
|
|
320
|
+
params: body,
|
|
321
|
+
httpStatus: 200,
|
|
322
|
+
usage,
|
|
323
|
+
captureImmediate: posthogCaptureImmediate,
|
|
324
|
+
})
|
|
325
|
+
} catch (error: any) {
|
|
326
|
+
await sendEventToPosthog({
|
|
327
|
+
client: this.phClient,
|
|
328
|
+
distinctId: posthogDistinctId,
|
|
329
|
+
traceId,
|
|
330
|
+
model: openAIParams.model,
|
|
331
|
+
provider: 'openai',
|
|
332
|
+
input: openAIParams.input,
|
|
333
|
+
output: [],
|
|
334
|
+
latency: 0,
|
|
335
|
+
baseURL: (this as any).baseURL ?? '',
|
|
336
|
+
params: body,
|
|
337
|
+
httpStatus: error?.status ? error.status : 500,
|
|
338
|
+
usage: { inputTokens: 0, outputTokens: 0 },
|
|
339
|
+
isError: true,
|
|
340
|
+
error: JSON.stringify(error),
|
|
341
|
+
captureImmediate: posthogCaptureImmediate,
|
|
342
|
+
})
|
|
343
|
+
}
|
|
344
|
+
})()
|
|
345
|
+
|
|
346
|
+
return stream2
|
|
347
|
+
}
|
|
348
|
+
return value
|
|
349
|
+
}) as APIPromise<Stream<OpenAIOrignal.Responses.ResponseStreamEvent>>
|
|
350
|
+
} else {
|
|
351
|
+
const wrappedPromise = parentPromise.then(
|
|
352
|
+
async (result) => {
|
|
353
|
+
if ('output' in result) {
|
|
354
|
+
const latency = (Date.now() - startTime) / 1000
|
|
355
|
+
await sendEventToPosthog({
|
|
356
|
+
client: this.phClient,
|
|
357
|
+
distinctId: posthogDistinctId,
|
|
358
|
+
traceId,
|
|
359
|
+
model: openAIParams.model,
|
|
360
|
+
provider: 'openai',
|
|
361
|
+
input: openAIParams.input,
|
|
362
|
+
output: result.output,
|
|
363
|
+
latency,
|
|
364
|
+
baseURL: (this as any).baseURL ?? '',
|
|
365
|
+
params: body,
|
|
366
|
+
httpStatus: 200,
|
|
367
|
+
usage: {
|
|
368
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
369
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
370
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
371
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
372
|
+
},
|
|
373
|
+
captureImmediate: posthogCaptureImmediate,
|
|
374
|
+
})
|
|
375
|
+
}
|
|
376
|
+
return result
|
|
377
|
+
},
|
|
378
|
+
async (error: any) => {
|
|
379
|
+
await sendEventToPosthog({
|
|
380
|
+
client: this.phClient,
|
|
381
|
+
distinctId: posthogDistinctId,
|
|
382
|
+
traceId,
|
|
383
|
+
model: openAIParams.model,
|
|
384
|
+
provider: 'openai',
|
|
385
|
+
input: openAIParams.input,
|
|
386
|
+
output: [],
|
|
387
|
+
latency: 0,
|
|
388
|
+
baseURL: (this as any).baseURL ?? '',
|
|
389
|
+
params: body,
|
|
390
|
+
httpStatus: error?.status ? error.status : 500,
|
|
391
|
+
usage: {
|
|
392
|
+
inputTokens: 0,
|
|
393
|
+
outputTokens: 0,
|
|
394
|
+
},
|
|
395
|
+
isError: true,
|
|
396
|
+
error: JSON.stringify(error),
|
|
397
|
+
captureImmediate: posthogCaptureImmediate,
|
|
398
|
+
})
|
|
399
|
+
throw error
|
|
400
|
+
}
|
|
401
|
+
) as APIPromise<OpenAIOrignal.Responses.Response>
|
|
402
|
+
|
|
403
|
+
return wrappedPromise
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
public parse<Params extends ResponsesCreateParamsBase, ParsedT = any>(
|
|
408
|
+
body: Params & MonitoringParams,
|
|
409
|
+
options?: RequestOptions
|
|
410
|
+
): APIPromise<ParsedResponse<ParsedT>> {
|
|
411
|
+
const {
|
|
412
|
+
posthogDistinctId,
|
|
413
|
+
posthogTraceId,
|
|
414
|
+
posthogProperties,
|
|
415
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
416
|
+
posthogPrivacyMode = false,
|
|
417
|
+
posthogGroups,
|
|
418
|
+
posthogCaptureImmediate,
|
|
419
|
+
...openAIParams
|
|
420
|
+
} = body
|
|
421
|
+
|
|
422
|
+
const traceId = posthogTraceId ?? uuidv4()
|
|
423
|
+
const startTime = Date.now()
|
|
424
|
+
|
|
425
|
+
// Create a temporary instance that bypasses our wrapped create method
|
|
426
|
+
const originalCreate = super.create.bind(this)
|
|
427
|
+
const originalSelf = this as any
|
|
428
|
+
const tempCreate = originalSelf.create
|
|
429
|
+
originalSelf.create = originalCreate
|
|
430
|
+
|
|
431
|
+
try {
|
|
432
|
+
const parentPromise = super.parse(openAIParams, options)
|
|
433
|
+
|
|
434
|
+
const wrappedPromise = parentPromise.then(
|
|
435
|
+
async (result) => {
|
|
436
|
+
const latency = (Date.now() - startTime) / 1000
|
|
437
|
+
await sendEventToPosthog({
|
|
438
|
+
client: this.phClient,
|
|
439
|
+
distinctId: posthogDistinctId,
|
|
440
|
+
traceId,
|
|
441
|
+
model: openAIParams.model,
|
|
442
|
+
provider: 'openai',
|
|
443
|
+
input: openAIParams.input,
|
|
444
|
+
output: result.output,
|
|
445
|
+
latency,
|
|
446
|
+
baseURL: (this as any).baseURL ?? '',
|
|
447
|
+
params: body,
|
|
448
|
+
httpStatus: 200,
|
|
449
|
+
usage: {
|
|
450
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
451
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
452
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
453
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
454
|
+
},
|
|
455
|
+
captureImmediate: posthogCaptureImmediate,
|
|
456
|
+
})
|
|
457
|
+
return result
|
|
458
|
+
},
|
|
459
|
+
async (error: any) => {
|
|
460
|
+
await sendEventToPosthog({
|
|
461
|
+
client: this.phClient,
|
|
462
|
+
distinctId: posthogDistinctId,
|
|
463
|
+
traceId,
|
|
464
|
+
model: openAIParams.model,
|
|
465
|
+
provider: 'openai',
|
|
466
|
+
input: openAIParams.input,
|
|
467
|
+
output: [],
|
|
468
|
+
latency: 0,
|
|
469
|
+
baseURL: (this as any).baseURL ?? '',
|
|
470
|
+
params: body,
|
|
471
|
+
httpStatus: error?.status ? error.status : 500,
|
|
472
|
+
usage: {
|
|
473
|
+
inputTokens: 0,
|
|
474
|
+
outputTokens: 0,
|
|
475
|
+
},
|
|
476
|
+
isError: true,
|
|
477
|
+
error: JSON.stringify(error),
|
|
478
|
+
captureImmediate: posthogCaptureImmediate,
|
|
479
|
+
})
|
|
480
|
+
throw error
|
|
481
|
+
}
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
return wrappedPromise as APIPromise<ParsedResponse<ParsedT>>
|
|
485
|
+
} finally {
|
|
486
|
+
// Restore our wrapped create method
|
|
487
|
+
originalSelf.create = tempCreate
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
218
492
|
export default PostHogOpenAI
|
|
219
493
|
|
|
220
494
|
export { PostHogOpenAI as OpenAI }
|
package/src/utils.ts
CHANGED
|
@@ -5,6 +5,7 @@ import AnthropicOriginal from '@anthropic-ai/sdk'
|
|
|
5
5
|
|
|
6
6
|
type ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams
|
|
7
7
|
type MessageCreateParams = AnthropicOriginal.Messages.MessageCreateParams
|
|
8
|
+
type ResponseCreateParams = OpenAIOrignal.Responses.ResponseCreateParams
|
|
8
9
|
|
|
9
10
|
// limit large outputs by truncating to 200kb (approx 200k bytes)
|
|
10
11
|
export const MAX_OUTPUT_SIZE = 200000
|
|
@@ -28,7 +29,7 @@ export interface CostOverride {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export const getModelParams = (
|
|
31
|
-
params: ((ChatCompletionCreateParamsBase | MessageCreateParams) & MonitoringParams) | null
|
|
32
|
+
params: ((ChatCompletionCreateParamsBase | MessageCreateParams | ResponseCreateParams) & MonitoringParams) | null
|
|
32
33
|
): Record<string, any> => {
|
|
33
34
|
if (!params) {
|
|
34
35
|
return {}
|
|
@@ -178,7 +179,7 @@ export type SendEventToPosthogParams = {
|
|
|
178
179
|
cacheReadInputTokens?: any
|
|
179
180
|
cacheCreationInputTokens?: any
|
|
180
181
|
}
|
|
181
|
-
params: (ChatCompletionCreateParamsBase | MessageCreateParams) & MonitoringParams
|
|
182
|
+
params: (ChatCompletionCreateParamsBase | MessageCreateParams | ResponseCreateParams) & MonitoringParams
|
|
182
183
|
isError?: boolean
|
|
183
184
|
error?: string
|
|
184
185
|
tools?: any
|
package/src/vercel/middleware.ts
CHANGED
|
@@ -18,8 +18,8 @@ interface ClientOptions {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
interface CreateInstrumentationMiddlewareOptions {
|
|
21
|
-
posthogDistinctId
|
|
22
|
-
posthogTraceId
|
|
21
|
+
posthogDistinctId?: string
|
|
22
|
+
posthogTraceId?: string
|
|
23
23
|
posthogProperties?: Record<string, any>
|
|
24
24
|
posthogPrivacyMode?: boolean
|
|
25
25
|
posthogGroups?: Record<string, any>
|
|
@@ -229,7 +229,7 @@ export const createInstrumentationMiddleware = (
|
|
|
229
229
|
await sendEventToPosthog({
|
|
230
230
|
client: phClient,
|
|
231
231
|
distinctId: options.posthogDistinctId,
|
|
232
|
-
traceId: options.posthogTraceId,
|
|
232
|
+
traceId: options.posthogTraceId ?? uuidv4(),
|
|
233
233
|
model: modelId,
|
|
234
234
|
provider: provider,
|
|
235
235
|
input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
|
|
@@ -252,7 +252,7 @@ export const createInstrumentationMiddleware = (
|
|
|
252
252
|
await sendEventToPosthog({
|
|
253
253
|
client: phClient,
|
|
254
254
|
distinctId: options.posthogDistinctId,
|
|
255
|
-
traceId: options.posthogTraceId,
|
|
255
|
+
traceId: options.posthogTraceId ?? uuidv4(),
|
|
256
256
|
model: modelId,
|
|
257
257
|
provider: model.provider,
|
|
258
258
|
input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
|
|
@@ -324,7 +324,7 @@ export const createInstrumentationMiddleware = (
|
|
|
324
324
|
await sendEventToPosthog({
|
|
325
325
|
client: phClient,
|
|
326
326
|
distinctId: options.posthogDistinctId,
|
|
327
|
-
traceId: options.posthogTraceId,
|
|
327
|
+
traceId: options.posthogTraceId ?? uuidv4(),
|
|
328
328
|
model: modelId,
|
|
329
329
|
provider: provider,
|
|
330
330
|
input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
|
|
@@ -347,7 +347,7 @@ export const createInstrumentationMiddleware = (
|
|
|
347
347
|
await sendEventToPosthog({
|
|
348
348
|
client: phClient,
|
|
349
349
|
distinctId: options.posthogDistinctId,
|
|
350
|
-
traceId: options.posthogTraceId,
|
|
350
|
+
traceId: options.posthogTraceId ?? uuidv4(),
|
|
351
351
|
model: modelId,
|
|
352
352
|
provider: provider,
|
|
353
353
|
input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
|
|
@@ -381,7 +381,7 @@ export const wrapVercelLanguageModel = (
|
|
|
381
381
|
const middleware = createInstrumentationMiddleware(phClient, model, {
|
|
382
382
|
...options,
|
|
383
383
|
posthogTraceId: traceId,
|
|
384
|
-
posthogDistinctId: options.posthogDistinctId
|
|
384
|
+
posthogDistinctId: options.posthogDistinctId,
|
|
385
385
|
})
|
|
386
386
|
|
|
387
387
|
const wrappedModel = wrapLanguageModel({
|
package/tests/gemini.test.ts
CHANGED
|
@@ -310,4 +310,35 @@ describe('PostHogGemini - Jest test suite', () => {
|
|
|
310
310
|
expect(vertexClient).toBeInstanceOf(PostHogGemini)
|
|
311
311
|
expect(vertexClient.models).toBeDefined()
|
|
312
312
|
})
|
|
313
|
+
|
|
314
|
+
conditionalTest('anonymous user - $process_person_profile set to false', async () => {
|
|
315
|
+
await client.models.generateContent({
|
|
316
|
+
model: 'gemini-2.0-flash-001',
|
|
317
|
+
contents: 'Hello',
|
|
318
|
+
posthogTraceId: 'trace-123',
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
expect(mockPostHogClient.capture).toHaveBeenCalledTimes(1)
|
|
322
|
+
const [captureArgs] = (mockPostHogClient.capture as jest.Mock).mock.calls
|
|
323
|
+
const { distinctId, properties } = captureArgs[0]
|
|
324
|
+
|
|
325
|
+
expect(distinctId).toBe('trace-123')
|
|
326
|
+
expect(properties['$process_person_profile']).toBe(false)
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
conditionalTest('identified user - $process_person_profile not set', async () => {
|
|
330
|
+
await client.models.generateContent({
|
|
331
|
+
model: 'gemini-2.0-flash-001',
|
|
332
|
+
contents: 'Hello',
|
|
333
|
+
posthogDistinctId: 'user-456',
|
|
334
|
+
posthogTraceId: 'trace-123',
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
expect(mockPostHogClient.capture).toHaveBeenCalledTimes(1)
|
|
338
|
+
const [captureArgs] = (mockPostHogClient.capture as jest.Mock).mock.calls
|
|
339
|
+
const { distinctId, properties } = captureArgs[0]
|
|
340
|
+
|
|
341
|
+
expect(distinctId).toBe('user-456')
|
|
342
|
+
expect(properties['$process_person_profile']).toBeUndefined()
|
|
343
|
+
})
|
|
313
344
|
})
|