@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
package/dist/index.mjs CHANGED
@@ -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;
@@ -412,7 +418,7 @@ function sanitizeValues(obj) {
412
418
  }
413
419
  //#endregion
414
420
  //#region package.json
415
- var version = "8.17.2";
421
+ var version = "8.18.1";
416
422
  //#endregion
417
423
  //#region src/serializeError.ts
418
424
  const DEFAULT_MAX_DEPTH = 3;
@@ -718,9 +724,38 @@ function isV3Model(model) {
718
724
  function getSpecificationVersion(model) {
719
725
  if (typeof model === "object" && model !== null && "specificationVersion" in model) return model.specificationVersion;
720
726
  }
721
- const redactFileData = (data, mediaType, client) => {
722
- if (data instanceof URL) return isFullAiCaptureEnabled(client) ? data.toString() : redactBase64DataUrl(data.toString(), data.protocol === "data:" ? mediaType : void 0);
723
- if (isString(data)) return isFullAiCaptureEnabled(client) ? data : redactBase64DataUrl(data, mediaType);
727
+ const dataUrlMediaType = (mediaType) => mediaType && /^[\w.+-]+\/[\w.+-]+$/.test(mediaType) ? mediaType : "application/octet-stream";
728
+ const MAX_EVENT_FILE_BYTES = 7864320;
729
+ const newFileBudget = () => ({ remaining: MAX_EVENT_FILE_BYTES });
730
+ const fitsBudget = (length, budget) => {
731
+ if (length > budget.remaining) return false;
732
+ budget.remaining -= length;
733
+ return true;
734
+ };
735
+ const fullCaptureDataUrl = (dataUrl, budget, mediaType) => fitsBudget(dataUrl.length, budget) ? dataUrl : String(redactBase64DataUrl(dataUrl, mediaType));
736
+ const redactFileData = (data, mediaType, client, budget) => {
737
+ if (data instanceof Uint8Array) {
738
+ if (!isFullAiCaptureEnabled(client)) return String(redactBase64DataUrl(data, mediaType));
739
+ const prefix = `data:${dataUrlMediaType(mediaType)};base64,`;
740
+ if (!fitsBudget(prefix.length + Math.ceil(data.length / 3) * 4, budget)) return `[base64 ${mediaType} redacted]`;
741
+ return prefix + uint8ArrayToBase64(data);
742
+ }
743
+ if (data instanceof URL) return isFullAiCaptureEnabled(client) ? fullCaptureDataUrl(data.toString(), budget, mediaType) : redactBase64DataUrl(data.toString(), data.protocol === "data:" ? mediaType : void 0);
744
+ if (isString(data)) {
745
+ if (!isFullAiCaptureEnabled(client)) return redactBase64DataUrl(data, mediaType);
746
+ if (/^(data:|https?:\/\/)/i.test(data)) return fullCaptureDataUrl(data, budget, mediaType);
747
+ return fullCaptureDataUrl(`data:${dataUrlMediaType(mediaType)};base64,${data}`, budget, mediaType);
748
+ }
749
+ };
750
+ const mapOutputFile = (item, client, budget) => {
751
+ let fileData = redactFileData(item.data, item.mediaType, client, budget) ?? `[binary ${item.mediaType} file]`;
752
+ if (!isFullAiCaptureEnabled(client) && typeof item.data === "string" && fileData === item.data && item.data.length > 1e3) fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
753
+ return {
754
+ type: "file",
755
+ name: "generated_file",
756
+ mediaType: item.mediaType,
757
+ data: fileData
758
+ };
724
759
  };
725
760
  const mapVercelParams = (params) => {
726
761
  return {
@@ -733,7 +768,7 @@ const mapVercelParams = (params) => {
733
768
  stream: params.stream
734
769
  };
735
770
  };
736
- const mapVercelPrompt = (messages, client) => {
771
+ const mapVercelPrompt = (messages, client, budget = newFileBudget()) => {
737
772
  const inputs = messages.map((message) => {
738
773
  let content;
739
774
  if (message.role === "system") content = [{
@@ -747,7 +782,7 @@ const mapVercelPrompt = (messages, client) => {
747
782
  };
748
783
  else if (c.type === "file") return {
749
784
  type: "file",
750
- file: redactFileData(c.data, c.mediaType, client) ?? "raw files not supported",
785
+ file: redactFileData(c.data, c.mediaType, client, budget) ?? "raw files not supported",
751
786
  mediaType: c.mediaType
752
787
  };
753
788
  else if (c.type === "reasoning") return {
@@ -808,7 +843,7 @@ const mapVercelPrompt = (messages, client) => {
808
843
  }
809
844
  return inputs;
810
845
  };
811
- const mapVercelOutput = (result, client) => {
846
+ const mapVercelOutput = (result, client, budget) => {
812
847
  const content = result.map((item) => {
813
848
  if (item.type === "text") return {
814
849
  type: "text",
@@ -830,16 +865,7 @@ const mapVercelOutput = (result, client) => {
830
865
  type: "reasoning",
831
866
  text: truncate(item.text, client)
832
867
  };
833
- if (item.type === "file") {
834
- let fileData = redactFileData(item.data, item.mediaType, client) ?? `[binary ${item.mediaType} file]`;
835
- if (!isFullAiCaptureEnabled(client) && typeof item.data === "string" && fileData === item.data && item.data.length > 1e3) fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
836
- return {
837
- type: "file",
838
- name: "generated_file",
839
- mediaType: item.mediaType,
840
- data: fileData
841
- };
842
- }
868
+ if (item.type === "file") return mapOutputFile(item, client, budget);
843
869
  if (item.type === "source") return {
844
870
  type: "source",
845
871
  sourceType: item.sourceType,
@@ -979,7 +1005,8 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
979
1005
  const result = await model.doGenerate(params);
980
1006
  const modelId = mergedOptions.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
981
1007
  const provider = mergedOptions.posthogProviderOverride ?? extractProvider(model);
982
- const content = mapVercelOutput(result.content ?? [], phClient);
1008
+ const fileBudget = newFileBudget();
1009
+ const content = mapVercelOutput(result.content ?? [], phClient, fileBudget);
983
1010
  const latency = (Date.now() - startTime) / 1e3;
984
1011
  const providerMetadata = result.providerMetadata;
985
1012
  const additionalTokenValues = extractAdditionalTokenValues(providerMetadata, result.usage);
@@ -1009,7 +1036,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1009
1036
  ...baseOptions,
1010
1037
  model: modelId,
1011
1038
  provider,
1012
- input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient),
1039
+ input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient, fileBudget),
1013
1040
  output: content,
1014
1041
  latency,
1015
1042
  baseURL,
@@ -1059,6 +1086,8 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1059
1086
  const provider = mergedOptions.posthogProviderOverride ?? extractProvider(model);
1060
1087
  const availableTools = extractAvailableToolCalls("vercel", params);
1061
1088
  const baseURL = extractBaseURL(model);
1089
+ const fileBudget = newFileBudget();
1090
+ const generatedFiles = [];
1062
1091
  const toolCallsInProgress = /* @__PURE__ */ new Map();
1063
1092
  const captureStreamGeneration = async (captureOptions) => {
1064
1093
  try {
@@ -1102,6 +1131,10 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1102
1131
  input: chunk.input
1103
1132
  });
1104
1133
  }
1134
+ if (chunk.type === "file") {
1135
+ if (firstTokenTime === void 0) firstTokenTime = Date.now();
1136
+ if (!privacyMode) generatedFiles.push(mapOutputFile(chunk, phClient, fileBudget));
1137
+ }
1105
1138
  if (chunk.type === "error") {
1106
1139
  hasInBandError = true;
1107
1140
  inBandError = chunk.error;
@@ -1144,6 +1177,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1144
1177
  arguments: toolCall.input
1145
1178
  }
1146
1179
  });
1180
+ content.push(...generatedFiles);
1147
1181
  const output = content.length > 0 ? [{
1148
1182
  role: "assistant",
1149
1183
  content: content.length === 1 && content[0].type === "text" ? content[0].text : content
@@ -1163,7 +1197,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
1163
1197
  ...baseOptions,
1164
1198
  model: modelId,
1165
1199
  provider,
1166
- input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient),
1200
+ input: privacyMode ? "" : mapVercelPrompt(params.prompt, phClient, fileBudget),
1167
1201
  output,
1168
1202
  latency,
1169
1203
  timeToFirstToken,