@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
@@ -302,6 +302,12 @@ const getModelParams = (params, responseServiceTier) => {
302
302
  if (responseServiceTier != null) modelParams.service_tier = responseServiceTier;
303
303
  return modelParams;
304
304
  };
305
+ const uint8ArrayToBase64 = (data) => {
306
+ if (typeof Buffer !== "undefined") return Buffer.from(data).toString("base64");
307
+ let binary = "";
308
+ for (let i = 0; i < data.length; i++) binary += String.fromCharCode(data[i]);
309
+ return btoa(binary);
310
+ };
305
311
  function toSafeString(input) {
306
312
  if (input === void 0 || input === null) return "";
307
313
  if (typeof input === "string") return input;
@@ -408,7 +414,7 @@ function sanitizeValues(obj) {
408
414
  }
409
415
  //#endregion
410
416
  //#region package.json
411
- var version = "8.17.2";
417
+ var version = "8.18.1";
412
418
  //#endregion
413
419
  //#region src/serializeError.ts
414
420
  const DEFAULT_MAX_DEPTH = 3;
@@ -714,9 +720,38 @@ function isV3Model(model) {
714
720
  function getSpecificationVersion(model) {
715
721
  if (typeof model === "object" && model !== null && "specificationVersion" in model) return model.specificationVersion;
716
722
  }
717
- const redactFileData = (data, mediaType, client) => {
718
- if (data instanceof URL) return isFullAiCaptureEnabled(client) ? data.toString() : redactBase64DataUrl(data.toString(), data.protocol === "data:" ? mediaType : void 0);
719
- if (isString(data)) return isFullAiCaptureEnabled(client) ? data : redactBase64DataUrl(data, mediaType);
723
+ const dataUrlMediaType = (mediaType) => mediaType && /^[\w.+-]+\/[\w.+-]+$/.test(mediaType) ? mediaType : "application/octet-stream";
724
+ const MAX_EVENT_FILE_BYTES = 7864320;
725
+ const newFileBudget = () => ({ remaining: MAX_EVENT_FILE_BYTES });
726
+ const fitsBudget = (length, budget) => {
727
+ if (length > budget.remaining) return false;
728
+ budget.remaining -= length;
729
+ return true;
730
+ };
731
+ const fullCaptureDataUrl = (dataUrl, budget, mediaType) => fitsBudget(dataUrl.length, budget) ? dataUrl : String(redactBase64DataUrl(dataUrl, mediaType));
732
+ const redactFileData = (data, mediaType, client, budget) => {
733
+ if (data instanceof Uint8Array) {
734
+ if (!isFullAiCaptureEnabled(client)) return String(redactBase64DataUrl(data, mediaType));
735
+ const prefix = `data:${dataUrlMediaType(mediaType)};base64,`;
736
+ if (!fitsBudget(prefix.length + Math.ceil(data.length / 3) * 4, budget)) return `[base64 ${mediaType} redacted]`;
737
+ return prefix + uint8ArrayToBase64(data);
738
+ }
739
+ if (data instanceof URL) return isFullAiCaptureEnabled(client) ? fullCaptureDataUrl(data.toString(), budget, mediaType) : redactBase64DataUrl(data.toString(), data.protocol === "data:" ? mediaType : void 0);
740
+ if (isString(data)) {
741
+ if (!isFullAiCaptureEnabled(client)) return redactBase64DataUrl(data, mediaType);
742
+ if (/^(data:|https?:\/\/)/i.test(data)) return fullCaptureDataUrl(data, budget, mediaType);
743
+ return fullCaptureDataUrl(`data:${dataUrlMediaType(mediaType)};base64,${data}`, budget, mediaType);
744
+ }
745
+ };
746
+ const mapOutputFile = (item, client, budget) => {
747
+ let fileData = redactFileData(item.data, item.mediaType, client, budget) ?? `[binary ${item.mediaType} file]`;
748
+ if (!isFullAiCaptureEnabled(client) && typeof item.data === "string" && fileData === item.data && item.data.length > 1e3) fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
749
+ return {
750
+ type: "file",
751
+ name: "generated_file",
752
+ mediaType: item.mediaType,
753
+ data: fileData
754
+ };
720
755
  };
721
756
  const mapVercelParams = (params) => {
722
757
  return {
@@ -729,7 +764,7 @@ const mapVercelParams = (params) => {
729
764
  stream: params.stream
730
765
  };
731
766
  };
732
- const mapVercelPrompt = (messages, client) => {
767
+ const mapVercelPrompt = (messages, client, budget = newFileBudget()) => {
733
768
  const inputs = messages.map((message) => {
734
769
  let content;
735
770
  if (message.role === "system") content = [{
@@ -743,7 +778,7 @@ const mapVercelPrompt = (messages, client) => {
743
778
  };
744
779
  else if (c.type === "file") return {
745
780
  type: "file",
746
- file: redactFileData(c.data, c.mediaType, client) ?? "raw files not supported",
781
+ file: redactFileData(c.data, c.mediaType, client, budget) ?? "raw files not supported",
747
782
  mediaType: c.mediaType
748
783
  };
749
784
  else if (c.type === "reasoning") return {
@@ -804,7 +839,7 @@ const mapVercelPrompt = (messages, client) => {
804
839
  }
805
840
  return inputs;
806
841
  };
807
- const mapVercelOutput = (result, client) => {
842
+ const mapVercelOutput = (result, client, budget) => {
808
843
  const content = result.map((item) => {
809
844
  if (item.type === "text") return {
810
845
  type: "text",
@@ -826,16 +861,7 @@ const mapVercelOutput = (result, client) => {
826
861
  type: "reasoning",
827
862
  text: truncate(item.text, client)
828
863
  };
829
- if (item.type === "file") {
830
- let fileData = redactFileData(item.data, item.mediaType, client) ?? `[binary ${item.mediaType} file]`;
831
- if (!isFullAiCaptureEnabled(client) && typeof item.data === "string" && fileData === item.data && item.data.length > 1e3) fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
832
- return {
833
- type: "file",
834
- name: "generated_file",
835
- mediaType: item.mediaType,
836
- data: fileData
837
- };
838
- }
864
+ if (item.type === "file") return mapOutputFile(item, client, budget);
839
865
  if (item.type === "source") return {
840
866
  type: "source",
841
867
  sourceType: item.sourceType,
@@ -975,7 +1001,8 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
975
1001
  const result = await model.doGenerate(params);
976
1002
  const modelId = mergedOptions.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
977
1003
  const provider = mergedOptions.posthogProviderOverride ?? extractProvider(model);
978
- const content = mapVercelOutput(result.content ?? [], phClient);
1004
+ const fileBudget = newFileBudget();
1005
+ const content = mapVercelOutput(result.content ?? [], phClient, fileBudget);
979
1006
  const latency = (Date.now() - startTime) / 1e3;
980
1007
  const providerMetadata = result.providerMetadata;
981
1008
  const additionalTokenValues = extractAdditionalTokenValues(providerMetadata, result.usage);
@@ -1005,7 +1032,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1005
1032
  ...baseOptions,
1006
1033
  model: modelId,
1007
1034
  provider,
1008
- input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient),
1035
+ input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient, fileBudget),
1009
1036
  output: content,
1010
1037
  latency,
1011
1038
  baseURL,
@@ -1055,6 +1082,8 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1055
1082
  const provider = mergedOptions.posthogProviderOverride ?? extractProvider(model);
1056
1083
  const availableTools = extractAvailableToolCalls("vercel", params);
1057
1084
  const baseURL = extractBaseURL(model);
1085
+ const fileBudget = newFileBudget();
1086
+ const generatedFiles = [];
1058
1087
  const toolCallsInProgress = /* @__PURE__ */ new Map();
1059
1088
  const captureStreamGeneration = async (captureOptions) => {
1060
1089
  try {
@@ -1098,6 +1127,10 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1098
1127
  input: chunk.input
1099
1128
  });
1100
1129
  }
1130
+ if (chunk.type === "file") {
1131
+ if (firstTokenTime === void 0) firstTokenTime = Date.now();
1132
+ if (!privacyMode) generatedFiles.push(mapOutputFile(chunk, phClient, fileBudget));
1133
+ }
1101
1134
  if (chunk.type === "error") {
1102
1135
  hasInBandError = true;
1103
1136
  inBandError = chunk.error;
@@ -1140,6 +1173,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1140
1173
  arguments: toolCall.input
1141
1174
  }
1142
1175
  });
1176
+ content.push(...generatedFiles);
1143
1177
  const output = content.length > 0 ? [{
1144
1178
  role: "assistant",
1145
1179
  content: content.length === 1 && content[0].type === "text" ? content[0].text : content
@@ -1159,7 +1193,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1159
1193
  ...baseOptions,
1160
1194
  model: modelId,
1161
1195
  provider,
1162
- input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient),
1196
+ input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient, fileBudget),
1163
1197
  output,
1164
1198
  latency,
1165
1199
  timeToFirstToken,