@posthog/ai 6.4.0 → 6.4.2

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 CHANGED
@@ -2,6 +2,7 @@ import OpenAIOrignal, { OpenAI, APIPromise, ClientOptions as ClientOptions$1, Az
2
2
  import { PostHog } from 'posthog-node';
3
3
  import { Stream } from 'openai/streaming';
4
4
  import { ParsedResponse } from 'openai/resources/responses/responses';
5
+ import { ResponseCreateParamsWithTools, ExtractParsedContentFromParams } from 'openai/lib/ResponsesParser';
5
6
  import { LanguageModelV2 } from '@ai-sdk/provider';
6
7
  import AnthropicOriginal, { APIPromise as APIPromise$1 } from '@anthropic-ai/sdk';
7
8
  import { Stream as Stream$1 } from '@anthropic-ai/sdk/streaming';
@@ -80,7 +81,7 @@ declare class WrappedResponses extends Responses {
80
81
  create(body: ResponsesCreateParamsNonStreaming & MonitoringParams, options?: RequestOptions$2): APIPromise<OpenAI.Responses.Response>;
81
82
  create(body: ResponsesCreateParamsStreaming & MonitoringParams, options?: RequestOptions$2): APIPromise<Stream<OpenAI.Responses.ResponseStreamEvent>>;
82
83
  create(body: ResponsesCreateParamsBase & MonitoringParams, options?: RequestOptions$2): APIPromise<OpenAI.Responses.Response | Stream<OpenAI.Responses.ResponseStreamEvent>>;
83
- parse<Params extends ResponsesCreateParamsBase, ParsedT = any>(body: Params & MonitoringParams, options?: RequestOptions$2): APIPromise<ParsedResponse<ParsedT>>;
84
+ parse<Params extends ResponseCreateParamsWithTools, ParsedT = ExtractParsedContentFromParams<Params>>(body: Params & MonitoringParams, options?: RequestOptions$2): APIPromise<ParsedResponse<ParsedT>>;
84
85
  }
85
86
  declare class WrappedEmbeddings$1 extends Embeddings {
86
87
  private readonly phClient;
@@ -187,6 +188,7 @@ declare class WrappedModels {
187
188
  generateContent(params: GenerateContentParameters & MonitoringParams): Promise<GenerateContentResponse>;
188
189
  generateContentStream(params: GenerateContentParameters & MonitoringParams): AsyncGenerator<GenerateContentResponse, void, unknown>;
189
190
  private formatInput;
191
+ private extractSystemInstruction;
190
192
  private formatInputForPostHog;
191
193
  }
192
194
 
package/dist/index.mjs CHANGED
@@ -6,7 +6,15 @@ import { wrapLanguageModel } from 'ai';
6
6
  import AnthropicOriginal from '@anthropic-ai/sdk';
7
7
  import { GoogleGenAI } from '@google/genai';
8
8
 
9
- var version = "6.4.0";
9
+ var version = "6.4.2";
10
+
11
+ // Type guards for safer type checking
12
+ const isString = value => {
13
+ return typeof value === 'string';
14
+ };
15
+ const isObject = value => {
16
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
17
+ };
10
18
 
11
19
  // limit large outputs by truncating to 200kb (approx 200k bytes)
12
20
  const MAX_OUTPUT_SIZE = 200000;
@@ -420,14 +428,49 @@ const sendEventToPosthog = async ({
420
428
  client.capture(event);
421
429
  }
422
430
  };
423
-
424
- // Type guards for safer type checking
425
- const isString = value => {
426
- return typeof value === 'string';
427
- };
428
- const isObject = value => {
429
- return value !== null && typeof value === 'object' && !Array.isArray(value);
430
- };
431
+ function formatOpenAIResponsesInput(input, instructions) {
432
+ const messages = [];
433
+ if (instructions) {
434
+ messages.push({
435
+ role: 'system',
436
+ content: instructions
437
+ });
438
+ }
439
+ if (Array.isArray(input)) {
440
+ for (const item of input) {
441
+ if (typeof item === 'string') {
442
+ messages.push({
443
+ role: 'user',
444
+ content: item
445
+ });
446
+ } else if (item && typeof item === 'object') {
447
+ const obj = item;
448
+ const role = isString(obj.role) ? obj.role : 'user';
449
+ const content = obj.content || obj.text || String(item);
450
+ messages.push({
451
+ role,
452
+ content: String(content)
453
+ });
454
+ } else {
455
+ messages.push({
456
+ role: 'user',
457
+ content: String(item)
458
+ });
459
+ }
460
+ }
461
+ } else if (typeof input === 'string') {
462
+ messages.push({
463
+ role: 'user',
464
+ content: input
465
+ });
466
+ } else if (input) {
467
+ messages.push({
468
+ role: 'user',
469
+ content: String(input)
470
+ });
471
+ }
472
+ return messages;
473
+ }
431
474
 
432
475
  const REDACTED_IMAGE_PLACEHOLDER = '[base64 image redacted]';
433
476
  // ============================================
@@ -507,17 +550,6 @@ const sanitizeOpenAIImage = item => {
507
550
  }
508
551
  return item;
509
552
  };
510
- const sanitizeOpenAIResponseImage = item => {
511
- if (!isObject(item)) return item;
512
- // Handle input_image format
513
- if (item.type === 'input_image' && 'image_url' in item) {
514
- return {
515
- ...item,
516
- image_url: redactBase64DataUrl(item.image_url)
517
- };
518
- }
519
- return item;
520
- };
521
553
  const sanitizeAnthropicImage = item => {
522
554
  if (!isObject(item)) return item;
523
555
  // Handle Anthropic's image format
@@ -600,9 +632,6 @@ const sanitizeLangChainImage = item => {
600
632
  const sanitizeOpenAI = data => {
601
633
  return processMessages(data, sanitizeOpenAIImage);
602
634
  };
603
- const sanitizeOpenAIResponse = data => {
604
- return processMessages(data, sanitizeOpenAIResponseImage);
605
- };
606
635
  const sanitizeAnthropic = data => {
607
636
  return processMessages(data, sanitizeAnthropicImage);
608
637
  };
@@ -822,7 +851,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
822
851
  await sendEventToPosthog({
823
852
  client: this.phClient,
824
853
  ...posthogParams,
825
- model: openAIParams.model,
854
+ model: String(openAIParams.model ?? ''),
826
855
  provider: 'openai',
827
856
  input: sanitizeOpenAI(openAIParams.messages),
828
857
  output: [],
@@ -889,7 +918,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
889
918
  //@ts-expect-error
890
919
  model: openAIParams.model,
891
920
  provider: 'openai',
892
- input: sanitizeOpenAIResponse(openAIParams.input),
921
+ input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
893
922
  output: finalContent,
894
923
  latency,
895
924
  baseURL: this.baseURL,
@@ -906,7 +935,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
906
935
  //@ts-expect-error
907
936
  model: openAIParams.model,
908
937
  provider: 'openai',
909
- input: sanitizeOpenAIResponse(openAIParams.input),
938
+ input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
910
939
  output: [],
911
940
  latency: 0,
912
941
  baseURL: this.baseURL,
@@ -936,7 +965,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
936
965
  //@ts-expect-error
937
966
  model: openAIParams.model,
938
967
  provider: 'openai',
939
- input: sanitizeOpenAIResponse(openAIParams.input),
968
+ input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
940
969
  output: formatResponseOpenAI({
941
970
  output: result.output
942
971
  }),
@@ -959,10 +988,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
959
988
  await sendEventToPosthog({
960
989
  client: this.phClient,
961
990
  ...posthogParams,
962
- //@ts-expect-error
963
- model: openAIParams.model,
991
+ model: String(openAIParams.model ?? ''),
964
992
  provider: 'openai',
965
- input: sanitizeOpenAIResponse(openAIParams.input),
993
+ input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
966
994
  output: [],
967
995
  latency: 0,
968
996
  baseURL: this.baseURL,
@@ -986,7 +1014,6 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
986
1014
  posthogParams
987
1015
  } = extractPosthogParams(body);
988
1016
  const startTime = Date.now();
989
- // Create a temporary instance that bypasses our wrapped create method
990
1017
  const originalCreate = super.create.bind(this);
991
1018
  const originalSelf = this;
992
1019
  const tempCreate = originalSelf.create;
@@ -998,10 +1025,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
998
1025
  await sendEventToPosthog({
999
1026
  client: this.phClient,
1000
1027
  ...posthogParams,
1001
- //@ts-expect-error
1002
- model: openAIParams.model,
1028
+ model: String(openAIParams.model ?? ''),
1003
1029
  provider: 'openai',
1004
- input: sanitizeOpenAIResponse(openAIParams.input),
1030
+ input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
1005
1031
  output: result.output,
1006
1032
  latency,
1007
1033
  baseURL: this.baseURL,
@@ -1020,10 +1046,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1020
1046
  await sendEventToPosthog({
1021
1047
  client: this.phClient,
1022
1048
  ...posthogParams,
1023
- //@ts-expect-error
1024
- model: openAIParams.model,
1049
+ model: String(openAIParams.model ?? ''),
1025
1050
  provider: 'openai',
1026
- input: sanitizeOpenAIResponse(openAIParams.input),
1051
+ input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
1027
1052
  output: [],
1028
1053
  latency: 0,
1029
1054
  baseURL: this.baseURL,
@@ -1235,7 +1260,7 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
1235
1260
  ...posthogParams,
1236
1261
  model: openAIParams.model,
1237
1262
  provider: 'azure',
1238
- input: openAIParams.messages,
1263
+ input: sanitizeOpenAI(openAIParams.messages),
1239
1264
  output: formattedOutput,
1240
1265
  latency,
1241
1266
  baseURL: this.baseURL,
@@ -1250,7 +1275,7 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
1250
1275
  ...posthogParams,
1251
1276
  model: openAIParams.model,
1252
1277
  provider: 'azure',
1253
- input: openAIParams.messages,
1278
+ input: sanitizeOpenAI(openAIParams.messages),
1254
1279
  output: [],
1255
1280
  latency: 0,
1256
1281
  baseURL: this.baseURL,
@@ -1463,8 +1488,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
1463
1488
  await sendEventToPosthog({
1464
1489
  client: this.phClient,
1465
1490
  ...posthogParams,
1466
- //@ts-expect-error
1467
- model: openAIParams.model,
1491
+ model: String(openAIParams.model ?? ''),
1468
1492
  provider: 'azure',
1469
1493
  input: openAIParams.input,
1470
1494
  output: result.output,
@@ -1484,8 +1508,7 @@ class WrappedResponses extends AzureOpenAI.Responses {
1484
1508
  await sendEventToPosthog({
1485
1509
  client: this.phClient,
1486
1510
  ...posthogParams,
1487
- //@ts-expect-error
1488
- model: openAIParams.model,
1511
+ model: String(openAIParams.model ?? ''),
1489
1512
  provider: 'azure',
1490
1513
  input: openAIParams.input,
1491
1514
  output: [],
@@ -2264,7 +2287,7 @@ class WrappedModels {
2264
2287
  ...posthogParams,
2265
2288
  model: geminiParams.model,
2266
2289
  provider: 'gemini',
2267
- input: this.formatInputForPostHog(geminiParams.contents),
2290
+ input: this.formatInputForPostHog(geminiParams),
2268
2291
  output: formatResponseGemini(response),
2269
2292
  latency,
2270
2293
  baseURL: 'https://generativelanguage.googleapis.com',
@@ -2286,7 +2309,7 @@ class WrappedModels {
2286
2309
  ...posthogParams,
2287
2310
  model: geminiParams.model,
2288
2311
  provider: 'gemini',
2289
- input: this.formatInputForPostHog(geminiParams.contents),
2312
+ input: this.formatInputForPostHog(geminiParams),
2290
2313
  output: [],
2291
2314
  latency,
2292
2315
  baseURL: 'https://generativelanguage.googleapis.com',
@@ -2381,7 +2404,7 @@ class WrappedModels {
2381
2404
  ...posthogParams,
2382
2405
  model: geminiParams.model,
2383
2406
  provider: 'gemini',
2384
- input: this.formatInputForPostHog(geminiParams.contents),
2407
+ input: this.formatInputForPostHog(geminiParams),
2385
2408
  output,
2386
2409
  latency,
2387
2410
  baseURL: 'https://generativelanguage.googleapis.com',
@@ -2397,7 +2420,7 @@ class WrappedModels {
2397
2420
  ...posthogParams,
2398
2421
  model: geminiParams.model,
2399
2422
  provider: 'gemini',
2400
- input: this.formatInputForPostHog(geminiParams.contents),
2423
+ input: this.formatInputForPostHog(geminiParams),
2401
2424
  output: [],
2402
2425
  latency,
2403
2426
  baseURL: 'https://generativelanguage.googleapis.com',
@@ -2432,19 +2455,19 @@ class WrappedModels {
2432
2455
  const obj = item;
2433
2456
  if ('text' in obj && obj.text) {
2434
2457
  return {
2435
- role: obj.role || 'user',
2458
+ role: isString(obj.role) ? obj.role : 'user',
2436
2459
  content: obj.text
2437
2460
  };
2438
2461
  }
2439
2462
  if ('content' in obj && obj.content) {
2440
2463
  return {
2441
- role: obj.role || 'user',
2464
+ role: isString(obj.role) ? obj.role : 'user',
2442
2465
  content: obj.content
2443
2466
  };
2444
2467
  }
2445
2468
  if ('parts' in obj && Array.isArray(obj.parts)) {
2446
2469
  return {
2447
- role: obj.role || 'user',
2470
+ role: isString(obj.role) ? obj.role : 'user',
2448
2471
  content: obj.parts.map(part => {
2449
2472
  if (part && typeof part === 'object' && 'text' in part) {
2450
2473
  return part.text;
@@ -2480,9 +2503,54 @@ class WrappedModels {
2480
2503
  content: String(contents)
2481
2504
  }];
2482
2505
  }
2483
- formatInputForPostHog(contents) {
2484
- const sanitized = sanitizeGemini(contents);
2485
- return this.formatInput(sanitized);
2506
+ extractSystemInstruction(params) {
2507
+ if (!params || typeof params !== 'object' || !params.config) {
2508
+ return null;
2509
+ }
2510
+ const config = params.config;
2511
+ if (!('systemInstruction' in config)) {
2512
+ return null;
2513
+ }
2514
+ const systemInstruction = config.systemInstruction;
2515
+ if (typeof systemInstruction === 'string') {
2516
+ return systemInstruction;
2517
+ }
2518
+ if (systemInstruction && typeof systemInstruction === 'object' && 'text' in systemInstruction) {
2519
+ return systemInstruction.text;
2520
+ }
2521
+ if (systemInstruction && typeof systemInstruction === 'object' && 'parts' in systemInstruction && Array.isArray(systemInstruction.parts)) {
2522
+ for (const part of systemInstruction.parts) {
2523
+ if (part && typeof part === 'object' && 'text' in part && typeof part.text === 'string') {
2524
+ return part.text;
2525
+ }
2526
+ }
2527
+ }
2528
+ if (Array.isArray(systemInstruction)) {
2529
+ for (const part of systemInstruction) {
2530
+ if (typeof part === 'string') {
2531
+ return part;
2532
+ }
2533
+ if (part && typeof part === 'object' && 'text' in part && typeof part.text === 'string') {
2534
+ return part.text;
2535
+ }
2536
+ }
2537
+ }
2538
+ return null;
2539
+ }
2540
+ formatInputForPostHog(params) {
2541
+ const sanitized = sanitizeGemini(params.contents);
2542
+ const messages = this.formatInput(sanitized);
2543
+ const systemInstruction = this.extractSystemInstruction(params);
2544
+ if (systemInstruction) {
2545
+ const hasSystemMessage = messages.some(msg => msg.role === 'system');
2546
+ if (!hasSystemMessage) {
2547
+ return [{
2548
+ role: 'system',
2549
+ content: systemInstruction
2550
+ }, ...messages];
2551
+ }
2552
+ }
2553
+ return messages;
2486
2554
  }
2487
2555
  }
2488
2556