@posthog/ai 8.14.4 → 8.15.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.
Files changed (47) hide show
  1. package/README.md +14 -0
  2. package/dist/adk/index.cjs +22 -7
  3. package/dist/adk/index.cjs.map +1 -1
  4. package/dist/adk/index.mjs +22 -7
  5. package/dist/adk/index.mjs.map +1 -1
  6. package/dist/anthropic/index.cjs +12 -5
  7. package/dist/anthropic/index.cjs.map +1 -1
  8. package/dist/anthropic/index.mjs +12 -5
  9. package/dist/anthropic/index.mjs.map +1 -1
  10. package/dist/claude-agent-sdk/index.cjs +12 -5
  11. package/dist/claude-agent-sdk/index.cjs.map +1 -1
  12. package/dist/claude-agent-sdk/index.mjs +12 -5
  13. package/dist/claude-agent-sdk/index.mjs.map +1 -1
  14. package/dist/gemini/index.cjs +403 -19
  15. package/dist/gemini/index.cjs.map +1 -1
  16. package/dist/gemini/index.d.ts +28 -0
  17. package/dist/gemini/index.mjs +403 -19
  18. package/dist/gemini/index.mjs.map +1 -1
  19. package/dist/index.cjs +12 -5
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.mjs +12 -5
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/langchain/index.cjs +12 -5
  24. package/dist/langchain/index.cjs.map +1 -1
  25. package/dist/langchain/index.mjs +12 -5
  26. package/dist/langchain/index.mjs.map +1 -1
  27. package/dist/langchain/middleware/index.cjs +12 -5
  28. package/dist/langchain/middleware/index.cjs.map +1 -1
  29. package/dist/langchain/middleware/index.mjs +12 -5
  30. package/dist/langchain/middleware/index.mjs.map +1 -1
  31. package/dist/openai/index.cjs +12 -5
  32. package/dist/openai/index.cjs.map +1 -1
  33. package/dist/openai/index.mjs +12 -5
  34. package/dist/openai/index.mjs.map +1 -1
  35. package/dist/openai-agents/index.cjs +12 -5
  36. package/dist/openai-agents/index.cjs.map +1 -1
  37. package/dist/openai-agents/index.mjs +12 -5
  38. package/dist/openai-agents/index.mjs.map +1 -1
  39. package/dist/otel/index.cjs +11 -4
  40. package/dist/otel/index.cjs.map +1 -1
  41. package/dist/otel/index.mjs +11 -4
  42. package/dist/otel/index.mjs.map +1 -1
  43. package/dist/vercel/index.cjs +12 -5
  44. package/dist/vercel/index.cjs.map +1 -1
  45. package/dist/vercel/index.mjs +12 -5
  46. package/dist/vercel/index.mjs.map +1 -1
  47. package/package.json +4 -3
@@ -96,6 +96,12 @@ const FILE_FAMILY_TYPES = /* @__PURE__ */ new Set([
96
96
  "media",
97
97
  "file-data"
98
98
  ]);
99
+ const TYPED_BINARY_DATA_TYPES = /* @__PURE__ */ new Set([
100
+ "image",
101
+ "audio",
102
+ "video",
103
+ "document"
104
+ ]);
99
105
  const KNOWN_AUDIO_FORMATS = /* @__PURE__ */ new Set([
100
106
  "wav",
101
107
  "mp3",
@@ -147,7 +153,8 @@ var MediaTypeContext = class MediaTypeContext {
147
153
  if (key.includes("image")) return "image";
148
154
  if (key.includes("file") || key.includes("document")) return "application/octet-stream";
149
155
  }
150
- hasExplicitBinaryMediaType() {
156
+ hasDefiniteBinaryData() {
157
+ if (this.parent && this.key === "data" && typeof this.parent.type === "string" && TYPED_BINARY_DATA_TYPES.has(this.parent.type)) return true;
151
158
  if (!this.explicitMediaType && (!this.parent || !this.key || !STRONG_CONTEXT_KEYS.has(this.key))) return false;
152
159
  const mediaType = this.inferFromSiblingMime();
153
160
  return mediaType !== void 0 && !mediaType.toLowerCase().startsWith("text/");
@@ -201,9 +208,9 @@ var BinaryContentRedactor = class {
201
208
  return out;
202
209
  }
203
210
  redactString(value, ctx) {
204
- const hasExplicitBinaryMediaType = ctx.hasExplicitBinaryMediaType();
205
- const recognitionValue = hasExplicitBinaryMediaType ? value.replace(/[\r\n]/g, "") : value;
206
- const minLength = hasExplicitBinaryMediaType ? Math.min(recognitionValue.length, STRONG_CONTEXT_MIN_LENGTH) : ctx.signalsBinary() ? STRONG_CONTEXT_MIN_LENGTH : WEAK_CONTEXT_MIN_LENGTH;
211
+ const hasDefiniteBinaryData = ctx.hasDefiniteBinaryData();
212
+ const recognitionValue = hasDefiniteBinaryData ? value.replace(/[\r\n]/g, "") : value;
213
+ const minLength = hasDefiniteBinaryData ? Math.min(recognitionValue.length, STRONG_CONTEXT_MIN_LENGTH) : ctx.signalsBinary() ? STRONG_CONTEXT_MIN_LENGTH : WEAK_CONTEXT_MIN_LENGTH;
207
214
  const recognition = this.recognizer.recognize(recognitionValue, minLength);
208
215
  switch (recognition.kind) {
209
216
  case "data-url": return this.placeholderFor(recognition.mediaType);
@@ -335,7 +342,11 @@ const formatResponseGemini = (response, client) => {
335
342
  if (response.candidates && Array.isArray(response.candidates)) {
336
343
  for (const candidate of response.candidates) if (candidate.content && candidate.content.parts) {
337
344
  const content = [];
338
- for (const part of candidate.content.parts) if (part.text) content.push({
345
+ for (const part of candidate.content.parts) if (part.thought === true && part.text) content.push({
346
+ type: "reasoning",
347
+ text: part.text
348
+ });
349
+ else if (part.text) content.push({
339
350
  type: "text",
340
351
  text: part.text
341
352
  });
@@ -452,7 +463,7 @@ function addDefaults(params) {
452
463
  }
453
464
  //#endregion
454
465
  //#region package.json
455
- var version = "8.14.4";
466
+ var version = "8.15.0";
456
467
  //#endregion
457
468
  //#region src/serializeError.ts
458
469
  const DEFAULT_MAX_DEPTH = 3;
@@ -718,7 +729,385 @@ function mapGeminiUsage(metadata, additionalUsage = {}) {
718
729
  };
719
730
  }
720
731
  //#endregion
732
+ //#region src/gemini/interactions.ts
733
+ function record(value) {
734
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
735
+ }
736
+ function string(value) {
737
+ return typeof value === "string" ? value : void 0;
738
+ }
739
+ function number(value) {
740
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
741
+ }
742
+ function isStream(value) {
743
+ return value !== null && typeof value === "object" && Symbol.asyncIterator in value;
744
+ }
745
+ function usageFromInteraction(value, model) {
746
+ const usage = record(value);
747
+ if (!usage) return {};
748
+ const cached = number(usage.total_cached_tokens);
749
+ const searches = Array.isArray(usage.grounding_tool_count) ? usage.grounding_tool_count.reduce((total, entry) => {
750
+ const grounding = record(entry);
751
+ return total + (grounding?.type === "google_search" ? number(grounding.count) ?? 0 : 0);
752
+ }, 0) : void 0;
753
+ const modelMajor = /^(?:models\/)?gemini-(\d+)/.exec(model ?? "")?.[1];
754
+ const webSearchCount = modelMajor === void 0 ? void 0 : Number(modelMajor) >= 3 ? searches : searches ? 1 : 0;
755
+ return {
756
+ inputTokens: number(usage.total_input_tokens),
757
+ outputTokens: number(usage.total_output_tokens),
758
+ reasoningTokens: number(usage.total_thought_tokens),
759
+ cacheReadInputTokens: cached,
760
+ ...cached !== void 0 ? { cacheReportingExclusive: false } : {},
761
+ webSearchCount,
762
+ rawUsage: usage
763
+ };
764
+ }
765
+ function functionArguments(value) {
766
+ if (typeof value !== "string") return record(value) ?? {};
767
+ try {
768
+ return record(JSON.parse(value)) ?? value;
769
+ } catch {
770
+ return value;
771
+ }
772
+ }
773
+ function outputFromSteps(steps, fallbackText) {
774
+ const content = [];
775
+ if (Array.isArray(steps)) for (const rawStep of steps) {
776
+ const step = record(rawStep);
777
+ if (step?.type === "model_output" && Array.isArray(step.content)) content.push(...step.content);
778
+ else if (step?.type === "function_call" && string(step.name)) content.push({
779
+ type: "function",
780
+ id: string(step.id),
781
+ function: {
782
+ name: step.name,
783
+ arguments: functionArguments(step.arguments)
784
+ }
785
+ });
786
+ }
787
+ if (content.length === 0 && fallbackText) content.push({
788
+ type: "text",
789
+ text: fallbackText
790
+ });
791
+ return content.length ? [{
792
+ role: "assistant",
793
+ content
794
+ }] : [];
795
+ }
796
+ function inputFromRequest(input, systemInstruction) {
797
+ const messages = [];
798
+ if (typeof systemInstruction === "string") messages.push({
799
+ role: "system",
800
+ content: systemInstruction
801
+ });
802
+ let userContent = [];
803
+ const flushUserContent = () => {
804
+ if (userContent.length) messages.push({
805
+ role: "user",
806
+ content: userContent
807
+ });
808
+ userContent = [];
809
+ };
810
+ for (const part of Array.isArray(input) ? input : [input]) {
811
+ const step = record(part);
812
+ if (step?.type === "text" || step?.type === "image" || step?.type === "audio" || step?.type === "video" || step?.type === "document") {
813
+ userContent.push(part);
814
+ continue;
815
+ }
816
+ flushUserContent();
817
+ if (step?.type === "function_result") messages.push({
818
+ role: "tool",
819
+ content: [{
820
+ type: "tool_result",
821
+ tool_use_id: step.call_id,
822
+ content: step.result
823
+ }]
824
+ });
825
+ else if (step?.type === "user_input") messages.push({
826
+ role: "user",
827
+ content: step.content ?? [part]
828
+ });
829
+ else if (step?.type === "model_output") messages.push({
830
+ role: "assistant",
831
+ content: step.content ?? [part]
832
+ });
833
+ else if (step?.type === "function_call") {
834
+ const output = outputFromSteps([part]);
835
+ messages.push(...output.length ? output : [{
836
+ role: "assistant",
837
+ content: [part]
838
+ }]);
839
+ } else messages.push({
840
+ role: "user",
841
+ content: part
842
+ });
843
+ }
844
+ flushUserContent();
845
+ return messages;
846
+ }
847
+ function safeTools(tools) {
848
+ if (!Array.isArray(tools)) return void 0;
849
+ return tools.map((tool) => ({
850
+ type: string(record(tool)?.type),
851
+ name: string(record(tool)?.name)
852
+ }));
853
+ }
854
+ function isFailure(status) {
855
+ return status === "failed" || status === "cancelled" || status === "incomplete" || status === "budget_exceeded";
856
+ }
857
+ var WrappedInteractions = class {
858
+ constructor(client, phClient) {
859
+ this.client = client;
860
+ this.phClient = phClient;
861
+ }
862
+ async create(params, options) {
863
+ const { providerParams, posthogParams } = extractPosthogParams(params);
864
+ const request = providerParams;
865
+ const requestData = record(request) ?? {};
866
+ if (requestData.background === true || typeof requestData.model !== "string" || requestData.agent !== void 0) throw new Error("Gemini Interactions tracing supports foreground model calls only");
867
+ const startTime = Date.now();
868
+ const capture = async (interaction, error, output, firstTokenTime) => {
869
+ try {
870
+ const privateCapture = withPrivacyMode(this.phClient, posthogParams.privacyMode, false) === null;
871
+ const model = string(interaction?.model) ?? string(requestData.model);
872
+ const generationConfig = record(requestData.generation_config);
873
+ const modelParameters = privateCapture ? {} : {
874
+ ...number(generationConfig?.max_output_tokens) !== void 0 ? { max_tokens: generationConfig?.max_output_tokens } : {},
875
+ ...string(generationConfig?.thinking_level) !== void 0 ? { thinking_level: generationConfig?.thinking_level } : {}
876
+ };
877
+ await captureAiGeneration(this.phClient, {
878
+ ...posthogParams,
879
+ model,
880
+ provider: "gemini",
881
+ input: privateCapture ? null : inputFromRequest(sanitizeGemini(requestData.input, this.phClient), sanitizeGemini(requestData.system_instruction, this.phClient)),
882
+ output: privateCapture ? null : sanitizeGemini(output ?? outputFromSteps(interaction?.steps, string(interaction?.output_text)), this.phClient),
883
+ latency: (Date.now() - startTime) / 1e3,
884
+ timeToFirstToken: firstTokenTime === void 0 ? void 0 : (firstTokenTime - startTime) / 1e3,
885
+ baseURL: "https://generativelanguage.googleapis.com",
886
+ modelParameters,
887
+ completionId: string(interaction?.id),
888
+ stopReason: string(interaction?.status),
889
+ servedServiceTier: string(interaction?.service_tier),
890
+ usage: usageFromInteraction(interaction?.usage, model),
891
+ tools: privateCapture ? void 0 : safeTools(requestData.tools),
892
+ error: privateCapture && error ? /* @__PURE__ */ new Error("Gemini interaction failed") : error
893
+ });
894
+ } catch {}
895
+ };
896
+ try {
897
+ if (!this.client.interactions?.create) throw new Error("Gemini Interactions requires @google/genai 2.18.0 or newer");
898
+ const result = await (options === void 0 ? this.client.interactions.create(request) : this.client.interactions.create(request, options));
899
+ if (requestData.stream === true) {
900
+ if (!isStream(result)) throw new Error("Gemini Interactions did not return a stream");
901
+ return this.wrapStream(result, capture);
902
+ }
903
+ if (isStream(result)) throw new Error("Gemini Interactions returned an unexpected stream");
904
+ const interaction = record(result);
905
+ let unsupportedSchema = false;
906
+ try {
907
+ unsupportedSchema = Array.isArray(interaction?.outputs) && !Array.isArray(interaction?.steps);
908
+ } catch {
909
+ return result;
910
+ }
911
+ if (unsupportedSchema) throw new Error("Gemini Interactions GA schema requires @google/genai 2.18.0 or newer");
912
+ try {
913
+ const status = interaction?.status;
914
+ if (status !== "queued" && status !== "in_progress") await capture(interaction, isFailure(status) ? /* @__PURE__ */ new Error(`Gemini interaction ${status}`) : void 0);
915
+ } catch {}
916
+ return result;
917
+ } catch (error) {
918
+ await capture(void 0, error);
919
+ throw error;
920
+ }
921
+ }
922
+ wrapStream(stream, capture) {
923
+ const reader = "getReader" in stream && typeof stream.getReader === "function" ? stream.getReader() : void 0;
924
+ const iterator = reader ? void 0 : stream[Symbol.asyncIterator]();
925
+ let readerReleased = false;
926
+ let errorIterator;
927
+ let readError;
928
+ const next = async () => {
929
+ if (!reader) return iterator.next();
930
+ try {
931
+ return await reader.read();
932
+ } catch (providerError) {
933
+ if (closed) throw providerError;
934
+ readError = providerError;
935
+ release();
936
+ try {
937
+ errorIterator = stream[Symbol.asyncIterator]();
938
+ } catch {
939
+ throw providerError;
940
+ }
941
+ try {
942
+ await errorIterator.next();
943
+ } finally {
944
+ try {
945
+ await errorIterator.return?.();
946
+ } catch {}
947
+ }
948
+ throw providerError;
949
+ }
950
+ };
951
+ const cancelSource = async (reason) => {
952
+ if (reader && !readerReleased) await reader.cancel(reason);
953
+ else if (reader) {
954
+ try {
955
+ await errorIterator?.return?.();
956
+ } catch {}
957
+ throw readError;
958
+ } else await iterator?.return?.();
959
+ };
960
+ const release = () => {
961
+ if (readerReleased) return;
962
+ try {
963
+ reader?.releaseLock();
964
+ readerReleased = true;
965
+ } catch {}
966
+ };
967
+ let interaction;
968
+ let latestUsage;
969
+ let finalUsage;
970
+ let error;
971
+ let firstTokenTime;
972
+ const steps = /* @__PURE__ */ new Map();
973
+ let completed = false;
974
+ let closed = false;
975
+ let cancelled = false;
976
+ let captured = false;
977
+ const observe = (event) => {
978
+ let schemaError;
979
+ try {
980
+ const item = record(event);
981
+ const eventType = item?.event_type;
982
+ if (eventType === "interaction.start" || eventType === "interaction.complete" || eventType === "interaction.delta" || typeof eventType === "string" && eventType.startsWith("content.")) schemaError = /* @__PURE__ */ new Error("Gemini Interactions GA schema requires @google/genai 2.18.0 or newer");
983
+ else {
984
+ const usage = record(record(item?.metadata)?.total_usage) ?? (eventType === "step.stop" ? record(item?.usage) : void 0);
985
+ if (usage) latestUsage = { ...usage };
986
+ if (eventType === "interaction.created") {
987
+ interaction = { ...record(item?.interaction) };
988
+ const initialUsage = record(interaction.usage);
989
+ if (initialUsage) latestUsage = { ...initialUsage };
990
+ } else if (eventType === "step.start") {
991
+ const index = number(item?.index);
992
+ const step = record(item?.step);
993
+ if (index !== void 0) steps.set(index, {
994
+ ...step,
995
+ content: Array.isArray(step?.content) ? step.content.map((item) => ({ ...record(item) })) : []
996
+ });
997
+ } else if (eventType === "step.delta") {
998
+ const index = number(item?.index);
999
+ const delta = record(item?.delta);
1000
+ const step = index === void 0 ? void 0 : steps.get(index);
1001
+ if (step && delta?.type === "text" && typeof delta.text === "string") {
1002
+ const last = step.content?.at(-1);
1003
+ const text = record(last);
1004
+ if (text?.type === "text") text.text = `${text.text ?? ""}${delta.text}`;
1005
+ else step.content?.push({
1006
+ type: "text",
1007
+ text: delta.text
1008
+ });
1009
+ firstTokenTime ??= Date.now();
1010
+ } else if (step && (delta?.type === "image" || delta?.type === "audio" || delta?.type === "video" || delta?.type === "document")) {
1011
+ step.content?.push({ ...delta });
1012
+ firstTokenTime ??= Date.now();
1013
+ } else if (step && delta?.type === "arguments_delta" && typeof delta.arguments === "string") {
1014
+ step.argumentChunks = `${step.argumentChunks ?? ""}${delta.arguments}`;
1015
+ firstTokenTime ??= Date.now();
1016
+ }
1017
+ } else if (eventType === "interaction.completed") {
1018
+ const result = record(item?.interaction);
1019
+ interaction = {
1020
+ ...interaction,
1021
+ ...result
1022
+ };
1023
+ completed = interaction.status !== "queued" && interaction.status !== "in_progress";
1024
+ const reportedUsage = record(result?.usage);
1025
+ if (reportedUsage) {
1026
+ latestUsage = { ...reportedUsage };
1027
+ if (completed) finalUsage = latestUsage;
1028
+ }
1029
+ if (isFailure(interaction.status)) error = /* @__PURE__ */ new Error(`Gemini interaction ${interaction.status}`);
1030
+ if (!completed) error = /* @__PURE__ */ new Error("Gemini interaction stream ended without a terminal result");
1031
+ } else if (eventType === "error") error = /* @__PURE__ */ new Error("Gemini interaction stream failed");
1032
+ }
1033
+ } catch {}
1034
+ if (schemaError) throw schemaError;
1035
+ };
1036
+ const finish = async (status, providerError) => {
1037
+ if (captured) return;
1038
+ captured = true;
1039
+ try {
1040
+ const streamedSteps = [...steps.entries()].sort(([left], [right]) => left - right).map(([, step]) => ({
1041
+ ...step,
1042
+ arguments: step.argumentChunks === void 0 ? step.arguments : functionArguments(step.argumentChunks)
1043
+ }));
1044
+ const output = outputFromSteps(Array.isArray(interaction?.steps) && interaction.steps.length > 0 ? interaction.steps : streamedSteps);
1045
+ await capture({
1046
+ ...interaction,
1047
+ usage: finalUsage ?? latestUsage,
1048
+ ...completed ? {} : { status }
1049
+ }, providerError ?? error ?? (!completed && status === "incomplete" ? /* @__PURE__ */ new Error("Gemini interaction stream ended without completion") : void 0), output, firstTokenTime);
1050
+ } catch {}
1051
+ };
1052
+ return new ReadableStream({
1053
+ async pull(controller) {
1054
+ try {
1055
+ const result = await next();
1056
+ if (closed) return;
1057
+ if (result.done) {
1058
+ closed = true;
1059
+ await finish("incomplete");
1060
+ release();
1061
+ if (!cancelled) controller.close();
1062
+ } else {
1063
+ observe(result.value);
1064
+ controller.enqueue(result.value);
1065
+ }
1066
+ } catch (providerError) {
1067
+ if (closed) return;
1068
+ closed = true;
1069
+ try {
1070
+ await cancelSource(providerError);
1071
+ } catch {}
1072
+ await finish("failed", providerError);
1073
+ release();
1074
+ if (!cancelled) controller.error(providerError);
1075
+ }
1076
+ },
1077
+ async cancel(reason) {
1078
+ cancelled = true;
1079
+ if (closed) return;
1080
+ closed = true;
1081
+ let cancellationError;
1082
+ try {
1083
+ await cancelSource(reason);
1084
+ } catch (providerError) {
1085
+ cancellationError = providerError;
1086
+ throw providerError;
1087
+ } finally {
1088
+ await finish("cancelled", cancellationError);
1089
+ release();
1090
+ }
1091
+ }
1092
+ });
1093
+ }
1094
+ };
1095
+ //#endregion
721
1096
  //#region src/gemini/index.ts
1097
+ /** Append streamed text to the last block of the same type, or start a new one. */
1098
+ function appendStreamedText(content, type, text) {
1099
+ for (let i = content.length - 1; i >= 0; i--) {
1100
+ const item = content[i];
1101
+ if (item.type === type) {
1102
+ item.text += text;
1103
+ return;
1104
+ }
1105
+ }
1106
+ content.push({
1107
+ type,
1108
+ text
1109
+ });
1110
+ }
722
1111
  const TOOL_RESULT_MAX_BYTES = 5e3;
723
1112
  function geminiFunctionResponseContent(response) {
724
1113
  return response.parts !== void 0 ? {
@@ -732,6 +1121,7 @@ var PostHogGoogleGenAI = class {
732
1121
  this.phClient = posthog;
733
1122
  this.client = new _google_genai.GoogleGenAI(geminiConfig);
734
1123
  this.models = new WrappedModels(this.client, this.phClient);
1124
+ this.interactions = new WrappedInteractions(this.client, this.phClient);
735
1125
  }
736
1126
  };
737
1127
  var WrappedModels = class {
@@ -797,18 +1187,8 @@ var WrappedModels = class {
797
1187
  if (firstTokenTime === void 0 && chunk.text) firstTokenTime = Date.now();
798
1188
  const chunkWebSearchCount = calculateGoogleWebSearchCount(chunk);
799
1189
  if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) usage.webSearchCount = chunkWebSearchCount;
800
- if (chunk.text) {
801
- let lastTextItem;
802
- for (let i = accumulatedContent.length - 1; i >= 0; i--) if (accumulatedContent[i].type === "text") {
803
- lastTextItem = accumulatedContent[i];
804
- break;
805
- }
806
- if (lastTextItem && lastTextItem.type === "text") lastTextItem.text += chunk.text;
807
- else accumulatedContent.push({
808
- type: "text",
809
- text: chunk.text
810
- });
811
- }
1190
+ for (const part of chunk.candidates?.[0]?.content?.parts ?? []) if (part.thought === true && part.text) appendStreamedText(accumulatedContent, "reasoning", part.text);
1191
+ if (chunk.text) appendStreamedText(accumulatedContent, "text", chunk.text);
812
1192
  if (chunk.candidates?.[0]?.finishReason) stopReason = chunk.candidates[0].finishReason;
813
1193
  if (chunk.candidates && Array.isArray(chunk.candidates)) {
814
1194
  for (const candidate of chunk.candidates) if (candidate.content && candidate.content.parts) {
@@ -917,7 +1297,11 @@ var WrappedModels = class {
917
1297
  }
918
1298
  formatPartsAsContentBlocks(parts) {
919
1299
  const blocks = [];
920
- for (const part of parts) if (part && typeof part === "object" && "text" in part && part.text) blocks.push({
1300
+ for (const part of parts) if (part && typeof part === "object" && "thought" in part && part.thought === true && "text" in part && part.text) blocks.push({
1301
+ type: "reasoning",
1302
+ text: String(part.text)
1303
+ });
1304
+ else if (part && typeof part === "object" && "text" in part && part.text) blocks.push({
921
1305
  type: "text",
922
1306
  text: String(part.text)
923
1307
  });