@posthog/ai 8.17.2 → 8.18.1

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.
Files changed (47) hide show
  1. package/README.md +22 -0
  2. package/dist/adk/index.cjs +8 -9
  3. package/dist/adk/index.cjs.map +1 -1
  4. package/dist/adk/index.mjs +8 -9
  5. package/dist/adk/index.mjs.map +1 -1
  6. package/dist/anthropic/index.cjs +1 -1
  7. package/dist/anthropic/index.cjs.map +1 -1
  8. package/dist/anthropic/index.mjs +1 -1
  9. package/dist/anthropic/index.mjs.map +1 -1
  10. package/dist/claude-agent-sdk/index.cjs +1 -1
  11. package/dist/claude-agent-sdk/index.cjs.map +1 -1
  12. package/dist/claude-agent-sdk/index.mjs +1 -1
  13. package/dist/claude-agent-sdk/index.mjs.map +1 -1
  14. package/dist/gemini/index.cjs +8 -9
  15. package/dist/gemini/index.cjs.map +1 -1
  16. package/dist/gemini/index.mjs +8 -9
  17. package/dist/gemini/index.mjs.map +1 -1
  18. package/dist/genkit/index.cjs +1001 -0
  19. package/dist/genkit/index.cjs.map +1 -0
  20. package/dist/genkit/index.d.ts +95 -0
  21. package/dist/genkit/index.mjs +1000 -0
  22. package/dist/genkit/index.mjs.map +1 -0
  23. package/dist/index.cjs +54 -20
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.mjs +54 -20
  26. package/dist/index.mjs.map +1 -1
  27. package/dist/langchain/index.cjs +1 -1
  28. package/dist/langchain/index.cjs.map +1 -1
  29. package/dist/langchain/index.mjs +1 -1
  30. package/dist/langchain/index.mjs.map +1 -1
  31. package/dist/langchain/middleware/index.cjs +1 -1
  32. package/dist/langchain/middleware/index.cjs.map +1 -1
  33. package/dist/langchain/middleware/index.mjs +1 -1
  34. package/dist/langchain/middleware/index.mjs.map +1 -1
  35. package/dist/openai/index.cjs +1 -1
  36. package/dist/openai/index.cjs.map +1 -1
  37. package/dist/openai/index.mjs +1 -1
  38. package/dist/openai/index.mjs.map +1 -1
  39. package/dist/openai-agents/index.cjs +1 -1
  40. package/dist/openai-agents/index.cjs.map +1 -1
  41. package/dist/openai-agents/index.mjs +1 -1
  42. package/dist/openai-agents/index.mjs.map +1 -1
  43. package/dist/vercel/index.cjs +54 -20
  44. package/dist/vercel/index.cjs.map +1 -1
  45. package/dist/vercel/index.mjs +54 -20
  46. package/dist/vercel/index.mjs.map +1 -1
  47. package/package.json +13 -3
@@ -301,6 +301,12 @@ const getModelParams = (params, responseServiceTier) => {
301
301
  if (responseServiceTier != null) modelParams.service_tier = responseServiceTier;
302
302
  return modelParams;
303
303
  };
304
+ const uint8ArrayToBase64 = (data) => {
305
+ if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
306
+ let binary = "";
307
+ for (let i = 0; i < data.length; i++) binary += String.fromCharCode(data[i]);
308
+ return btoa(binary);
309
+ };
304
310
  function toSafeString(input) {
305
311
  if (input === void 0 || input === null) return "";
306
312
  if (typeof input === "string") return input;
@@ -407,7 +413,7 @@ function sanitizeValues(obj) {
407
413
  }
408
414
  //#endregion
409
415
  //#region package.json
410
- var version = "8.17.2";
416
+ var version = "8.18.1";
411
417
  //#endregion
412
418
  //#region src/serializeError.ts
413
419
  const DEFAULT_MAX_DEPTH = 3;
@@ -713,9 +719,38 @@ function isV3Model(model) {
713
719
  function getSpecificationVersion(model) {
714
720
  if (typeof model === "object" && model !== null && "specificationVersion" in model) return model.specificationVersion;
715
721
  }
716
- const redactFileData = (data, mediaType, client) => {
717
- if (data instanceof URL) return isFullAiCaptureEnabled(client) ? data.toString() : redactBase64DataUrl(data.toString(), data.protocol === "data:" ? mediaType : void 0);
718
- if (isString(data)) return isFullAiCaptureEnabled(client) ? data : redactBase64DataUrl(data, mediaType);
722
+ const dataUrlMediaType = (mediaType) => mediaType && /^[\w.+-]+\/[\w.+-]+$/.test(mediaType) ? mediaType : "application/octet-stream";
723
+ const MAX_EVENT_FILE_BYTES = 7864320;
724
+ const newFileBudget = () => ({ remaining: MAX_EVENT_FILE_BYTES });
725
+ const fitsBudget = (length, budget) => {
726
+ if (length > budget.remaining) return false;
727
+ budget.remaining -= length;
728
+ return true;
729
+ };
730
+ const fullCaptureDataUrl = (dataUrl, budget, mediaType) => fitsBudget(dataUrl.length, budget) ? dataUrl : String(redactBase64DataUrl(dataUrl, mediaType));
731
+ const redactFileData = (data, mediaType, client, budget) => {
732
+ if (data instanceof Uint8Array) {
733
+ if (!isFullAiCaptureEnabled(client)) return String(redactBase64DataUrl(data, mediaType));
734
+ const prefix = `data:${dataUrlMediaType(mediaType)};base64,`;
735
+ if (!fitsBudget(prefix.length + Math.ceil(data.length / 3) * 4, budget)) return `[base64 ${mediaType} redacted]`;
736
+ return prefix + uint8ArrayToBase64(data);
737
+ }
738
+ if (data instanceof URL) return isFullAiCaptureEnabled(client) ? fullCaptureDataUrl(data.toString(), budget, mediaType) : redactBase64DataUrl(data.toString(), data.protocol === "data:" ? mediaType : void 0);
739
+ if (isString(data)) {
740
+ if (!isFullAiCaptureEnabled(client)) return redactBase64DataUrl(data, mediaType);
741
+ if (/^(data:|https?:\/\/)/i.test(data)) return fullCaptureDataUrl(data, budget, mediaType);
742
+ return fullCaptureDataUrl(`data:${dataUrlMediaType(mediaType)};base64,${data}`, budget, mediaType);
743
+ }
744
+ };
745
+ const mapOutputFile = (item, client, budget) => {
746
+ let fileData = redactFileData(item.data, item.mediaType, client, budget) ?? `[binary ${item.mediaType} file]`;
747
+ if (!isFullAiCaptureEnabled(client) && typeof item.data === "string" && fileData === item.data && item.data.length > 1e3) fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
748
+ return {
749
+ type: "file",
750
+ name: "generated_file",
751
+ mediaType: item.mediaType,
752
+ data: fileData
753
+ };
719
754
  };
720
755
  const mapVercelParams = (params) => {
721
756
  return {
@@ -728,7 +763,7 @@ const mapVercelParams = (params) => {
728
763
  stream: params.stream
729
764
  };
730
765
  };
731
- const mapVercelPrompt = (messages, client) => {
766
+ const mapVercelPrompt = (messages, client, budget = newFileBudget()) => {
732
767
  const inputs = messages.map((message) => {
733
768
  let content;
734
769
  if (message.role === "system") content = [{
@@ -742,7 +777,7 @@ const mapVercelPrompt = (messages, client) => {
742
777
  };
743
778
  else if (c.type === "file") return {
744
779
  type: "file",
745
- file: redactFileData(c.data, c.mediaType, client) ?? "raw files not supported",
780
+ file: redactFileData(c.data, c.mediaType, client, budget) ?? "raw files not supported",
746
781
  mediaType: c.mediaType
747
782
  };
748
783
  else if (c.type === "reasoning") return {
@@ -803,7 +838,7 @@ const mapVercelPrompt = (messages, client) => {
803
838
  }
804
839
  return inputs;
805
840
  };
806
- const mapVercelOutput = (result, client) => {
841
+ const mapVercelOutput = (result, client, budget) => {
807
842
  const content = result.map((item) => {
808
843
  if (item.type === "text") return {
809
844
  type: "text",
@@ -825,16 +860,7 @@ const mapVercelOutput = (result, client) => {
825
860
  type: "reasoning",
826
861
  text: truncate(item.text, client)
827
862
  };
828
- if (item.type === "file") {
829
- let fileData = redactFileData(item.data, item.mediaType, client) ?? `[binary ${item.mediaType} file]`;
830
- if (!isFullAiCaptureEnabled(client) && typeof item.data === "string" && fileData === item.data && item.data.length > 1e3) fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
831
- return {
832
- type: "file",
833
- name: "generated_file",
834
- mediaType: item.mediaType,
835
- data: fileData
836
- };
837
- }
863
+ if (item.type === "file") return mapOutputFile(item, client, budget);
838
864
  if (item.type === "source") return {
839
865
  type: "source",
840
866
  sourceType: item.sourceType,
@@ -974,7 +1000,8 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
974
1000
  const result = await model.doGenerate(params);
975
1001
  const modelId = mergedOptions.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
976
1002
  const provider = mergedOptions.posthogProviderOverride ?? extractProvider(model);
977
- const content = mapVercelOutput(result.content ?? [], phClient);
1003
+ const fileBudget = newFileBudget();
1004
+ const content = mapVercelOutput(result.content ?? [], phClient, fileBudget);
978
1005
  const latency = (Date.now() - startTime) / 1e3;
979
1006
  const providerMetadata = result.providerMetadata;
980
1007
  const additionalTokenValues = extractAdditionalTokenValues(providerMetadata, result.usage);
@@ -1004,7 +1031,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1004
1031
  ...baseOptions,
1005
1032
  model: modelId,
1006
1033
  provider,
1007
- input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient),
1034
+ input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient, fileBudget),
1008
1035
  output: content,
1009
1036
  latency,
1010
1037
  baseURL,
@@ -1054,6 +1081,8 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1054
1081
  const provider = mergedOptions.posthogProviderOverride ?? extractProvider(model);
1055
1082
  const availableTools = extractAvailableToolCalls("vercel", params);
1056
1083
  const baseURL = extractBaseURL(model);
1084
+ const fileBudget = newFileBudget();
1085
+ const generatedFiles = [];
1057
1086
  const toolCallsInProgress = /* @__PURE__ */ new Map();
1058
1087
  const captureStreamGeneration = async (captureOptions) => {
1059
1088
  try {
@@ -1097,6 +1126,10 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1097
1126
  input: chunk.input
1098
1127
  });
1099
1128
  }
1129
+ if (chunk.type === "file") {
1130
+ if (firstTokenTime === void 0) firstTokenTime = Date.now();
1131
+ if (!privacyMode) generatedFiles.push(mapOutputFile(chunk, phClient, fileBudget));
1132
+ }
1100
1133
  if (chunk.type === "error") {
1101
1134
  hasInBandError = true;
1102
1135
  inBandError = chunk.error;
@@ -1139,6 +1172,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1139
1172
  arguments: toolCall.input
1140
1173
  }
1141
1174
  });
1175
+ content.push(...generatedFiles);
1142
1176
  const output = content.length > 0 ? [{
1143
1177
  role: "assistant",
1144
1178
  content: content.length === 1 && content[0].type === "text" ? content[0].text : content
@@ -1158,7 +1192,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1158
1192
  ...baseOptions,
1159
1193
  model: modelId,
1160
1194
  provider,
1161
- input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient),
1195
+ input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient, fileBudget),
1162
1196
  output,
1163
1197
  latency,
1164
1198
  timeToFirstToken,