@ai-sdk/langchain 1.0.0-canary.7 → 1.0.0-canary.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @ai-sdk/langchain
2
2
 
3
+ ## 1.0.0-canary.8
4
+
5
+ ### Patch Changes
6
+
7
+ - bc3109f: chore (ai): push stream-callbacks into langchain/llamaindex adapters
8
+ - Updated dependencies [13fef90]
9
+ - Updated dependencies [e90d45d]
10
+ - Updated dependencies [bc3109f]
11
+ - Updated dependencies [496bbc1]
12
+ - Updated dependencies [da70d79]
13
+ - Updated dependencies [bcea599]
14
+ - Updated dependencies [48d675a]
15
+ - Updated dependencies [c7710a9]
16
+ - Updated dependencies [35fc02c]
17
+ - Updated dependencies [b983b51]
18
+ - ai@5.0.0-canary.20
19
+
3
20
  ## 1.0.0-canary.7
4
21
 
5
22
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,4 +1,16 @@
1
- import { StreamCallbacks } from 'ai/internal';
1
+ /**
2
+ * Configuration options and helper callback methods for stream lifecycle events.
3
+ */
4
+ interface StreamCallbacks {
5
+ /** `onStart`: Called once when the stream is initialized. */
6
+ onStart?: () => Promise<void> | void;
7
+ /** `onFinal`: Called once when the stream is closed with the final completion message. */
8
+ onFinal?: (completion: string) => Promise<void> | void;
9
+ /** `onToken`: Called for each tokenized message. */
10
+ onToken?: (token: string) => Promise<void> | void;
11
+ /** `onText`: Called for each text chunk. */
12
+ onText?: (text: string) => Promise<void> | void;
13
+ }
2
14
 
3
15
  type LangChainImageDetail = 'auto' | 'low' | 'high';
4
16
  type LangChainMessageContentText = {
@@ -33,46 +45,47 @@ The following streams are supported:
33
45
  - `string` streams (LangChain `StringOutputParser` output)
34
46
  */
35
47
  declare function toDataStream(stream: ReadableStream<LangChainStreamEvent> | ReadableStream<LangChainAIMessageChunk> | ReadableStream<string>, callbacks?: StreamCallbacks): ReadableStream<{
36
- value: string;
37
48
  type: "text";
49
+ value: string;
38
50
  } | {
39
- value: any[];
40
51
  type: "data";
52
+ value: any[];
41
53
  } | {
42
- value: string;
43
54
  type: "error";
55
+ value: string;
44
56
  } | {
45
- value: any[];
46
57
  type: "message-annotations";
58
+ value: any[];
47
59
  } | {
60
+ type: "tool-call";
48
61
  value: {
49
- toolName: string;
50
62
  toolCallId: string;
63
+ toolName: string;
51
64
  args?: unknown;
52
65
  };
53
- type: "tool-call";
54
66
  } | {
67
+ type: "tool-result";
55
68
  value: {
56
69
  toolCallId: string;
57
70
  result?: unknown;
58
71
  providerMetadata?: any;
59
72
  };
60
- type: "tool-result";
61
73
  } | {
74
+ type: "tool-call-streaming-start";
62
75
  value: {
63
- toolName: string;
64
76
  toolCallId: string;
77
+ toolName: string;
65
78
  };
66
- type: "tool-call-streaming-start";
67
79
  } | {
80
+ type: "tool-call-delta";
68
81
  value: {
69
82
  toolCallId: string;
70
83
  argsTextDelta: string;
71
84
  };
72
- type: "tool-call-delta";
73
85
  } | {
86
+ type: "finish-message";
74
87
  value: {
75
- finishReason: "length" | "unknown" | "stop" | "content-filter" | "tool-calls" | "error" | "other";
88
+ finishReason: "length" | "stop" | "tool-calls" | "content-filter" | "other" | "error" | "unknown";
76
89
  usage?: {
77
90
  inputTokens?: number | undefined;
78
91
  outputTokens?: number | undefined;
@@ -81,10 +94,10 @@ declare function toDataStream(stream: ReadableStream<LangChainStreamEvent> | Rea
81
94
  cachedInputTokens?: number | undefined;
82
95
  } | undefined;
83
96
  };
84
- type: "finish-message";
85
97
  } | {
98
+ type: "finish-step";
86
99
  value: {
87
- finishReason: "length" | "unknown" | "stop" | "content-filter" | "tool-calls" | "error" | "other";
100
+ finishReason: "length" | "stop" | "tool-calls" | "content-filter" | "other" | "error" | "unknown";
88
101
  isContinued: boolean;
89
102
  usage?: {
90
103
  inputTokens?: number | undefined;
@@ -94,37 +107,36 @@ declare function toDataStream(stream: ReadableStream<LangChainStreamEvent> | Rea
94
107
  cachedInputTokens?: number | undefined;
95
108
  } | undefined;
96
109
  };
97
- type: "finish-step";
98
110
  } | {
111
+ type: "start-step";
99
112
  value: {
100
113
  messageId: string;
101
114
  };
102
- type: "start-step";
103
115
  } | {
116
+ type: "reasoning";
104
117
  value: {
105
118
  text: string;
106
119
  providerMetadata?: Record<string, any> | undefined;
107
120
  };
108
- type: "reasoning";
109
121
  } | {
122
+ type: "source";
110
123
  value: {
111
124
  type: "source";
112
- id: string;
113
125
  sourceType: "url";
114
126
  url: string;
127
+ id: string;
115
128
  providerMetadata?: any;
116
129
  title?: string | undefined;
117
130
  };
118
- type: "source";
119
131
  } | {
132
+ type: "file";
120
133
  value: {
121
- mediaType: string;
122
134
  url: string;
135
+ mediaType: string;
123
136
  };
124
- type: "file";
125
137
  } | {
126
- value: null;
127
138
  type: "reasoning-part-finish";
139
+ value: null;
128
140
  }>;
129
141
 
130
142
  export { toDataStream };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,16 @@
1
- import { StreamCallbacks } from 'ai/internal';
1
+ /**
2
+ * Configuration options and helper callback methods for stream lifecycle events.
3
+ */
4
+ interface StreamCallbacks {
5
+ /** `onStart`: Called once when the stream is initialized. */
6
+ onStart?: () => Promise<void> | void;
7
+ /** `onFinal`: Called once when the stream is closed with the final completion message. */
8
+ onFinal?: (completion: string) => Promise<void> | void;
9
+ /** `onToken`: Called for each tokenized message. */
10
+ onToken?: (token: string) => Promise<void> | void;
11
+ /** `onText`: Called for each text chunk. */
12
+ onText?: (text: string) => Promise<void> | void;
13
+ }
2
14
 
3
15
  type LangChainImageDetail = 'auto' | 'low' | 'high';
4
16
  type LangChainMessageContentText = {
@@ -33,46 +45,47 @@ The following streams are supported:
33
45
  - `string` streams (LangChain `StringOutputParser` output)
34
46
  */
35
47
  declare function toDataStream(stream: ReadableStream<LangChainStreamEvent> | ReadableStream<LangChainAIMessageChunk> | ReadableStream<string>, callbacks?: StreamCallbacks): ReadableStream<{
36
- value: string;
37
48
  type: "text";
49
+ value: string;
38
50
  } | {
39
- value: any[];
40
51
  type: "data";
52
+ value: any[];
41
53
  } | {
42
- value: string;
43
54
  type: "error";
55
+ value: string;
44
56
  } | {
45
- value: any[];
46
57
  type: "message-annotations";
58
+ value: any[];
47
59
  } | {
60
+ type: "tool-call";
48
61
  value: {
49
- toolName: string;
50
62
  toolCallId: string;
63
+ toolName: string;
51
64
  args?: unknown;
52
65
  };
53
- type: "tool-call";
54
66
  } | {
67
+ type: "tool-result";
55
68
  value: {
56
69
  toolCallId: string;
57
70
  result?: unknown;
58
71
  providerMetadata?: any;
59
72
  };
60
- type: "tool-result";
61
73
  } | {
74
+ type: "tool-call-streaming-start";
62
75
  value: {
63
- toolName: string;
64
76
  toolCallId: string;
77
+ toolName: string;
65
78
  };
66
- type: "tool-call-streaming-start";
67
79
  } | {
80
+ type: "tool-call-delta";
68
81
  value: {
69
82
  toolCallId: string;
70
83
  argsTextDelta: string;
71
84
  };
72
- type: "tool-call-delta";
73
85
  } | {
86
+ type: "finish-message";
74
87
  value: {
75
- finishReason: "length" | "unknown" | "stop" | "content-filter" | "tool-calls" | "error" | "other";
88
+ finishReason: "length" | "stop" | "tool-calls" | "content-filter" | "other" | "error" | "unknown";
76
89
  usage?: {
77
90
  inputTokens?: number | undefined;
78
91
  outputTokens?: number | undefined;
@@ -81,10 +94,10 @@ declare function toDataStream(stream: ReadableStream<LangChainStreamEvent> | Rea
81
94
  cachedInputTokens?: number | undefined;
82
95
  } | undefined;
83
96
  };
84
- type: "finish-message";
85
97
  } | {
98
+ type: "finish-step";
86
99
  value: {
87
- finishReason: "length" | "unknown" | "stop" | "content-filter" | "tool-calls" | "error" | "other";
100
+ finishReason: "length" | "stop" | "tool-calls" | "content-filter" | "other" | "error" | "unknown";
88
101
  isContinued: boolean;
89
102
  usage?: {
90
103
  inputTokens?: number | undefined;
@@ -94,37 +107,36 @@ declare function toDataStream(stream: ReadableStream<LangChainStreamEvent> | Rea
94
107
  cachedInputTokens?: number | undefined;
95
108
  } | undefined;
96
109
  };
97
- type: "finish-step";
98
110
  } | {
111
+ type: "start-step";
99
112
  value: {
100
113
  messageId: string;
101
114
  };
102
- type: "start-step";
103
115
  } | {
116
+ type: "reasoning";
104
117
  value: {
105
118
  text: string;
106
119
  providerMetadata?: Record<string, any> | undefined;
107
120
  };
108
- type: "reasoning";
109
121
  } | {
122
+ type: "source";
110
123
  value: {
111
124
  type: "source";
112
- id: string;
113
125
  sourceType: "url";
114
126
  url: string;
127
+ id: string;
115
128
  providerMetadata?: any;
116
129
  title?: string | undefined;
117
130
  };
118
- type: "source";
119
131
  } | {
132
+ type: "file";
120
133
  value: {
121
- mediaType: string;
122
134
  url: string;
135
+ mediaType: string;
123
136
  };
124
- type: "file";
125
137
  } | {
126
- value: null;
127
138
  type: "reasoning-part-finish";
139
+ value: null;
128
140
  }>;
129
141
 
130
142
  export { toDataStream };
package/dist/index.js CHANGED
@@ -24,8 +24,30 @@ __export(src_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(src_exports);
26
26
 
27
+ // src/stream-callbacks.ts
28
+ function createCallbacksTransformer(callbacks = {}) {
29
+ let aggregatedResponse = "";
30
+ return new TransformStream({
31
+ async start() {
32
+ if (callbacks.onStart) await callbacks.onStart();
33
+ },
34
+ async transform(message, controller) {
35
+ controller.enqueue(message);
36
+ aggregatedResponse += message;
37
+ if (callbacks.onToken) await callbacks.onToken(message);
38
+ if (callbacks.onText && typeof message === "string") {
39
+ await callbacks.onText(message);
40
+ }
41
+ },
42
+ async flush() {
43
+ if (callbacks.onFinal) {
44
+ await callbacks.onFinal(aggregatedResponse);
45
+ }
46
+ }
47
+ });
48
+ }
49
+
27
50
  // src/langchain-adapter.ts
28
- var import_internal = require("ai/internal");
29
51
  function toDataStream(stream, callbacks) {
30
52
  return stream.pipeThrough(
31
53
  new TransformStream({
@@ -47,7 +69,7 @@ function toDataStream(stream, callbacks) {
47
69
  forwardAIMessageChunk(value, controller);
48
70
  }
49
71
  })
50
- ).pipeThrough((0, import_internal.createCallbacksTransformer)(callbacks)).pipeThrough(
72
+ ).pipeThrough(createCallbacksTransformer(callbacks)).pipeThrough(
51
73
  new TransformStream({
52
74
  transform: async (chunk, controller) => {
53
75
  controller.enqueue({ type: "text", value: chunk });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/langchain-adapter.ts"],"sourcesContent":["export * from './langchain-adapter';\n","import { DataStreamPart } from 'ai';\nimport { createCallbacksTransformer, StreamCallbacks } from 'ai/internal';\n\ntype LangChainImageDetail = 'auto' | 'low' | 'high';\n\ntype LangChainMessageContentText = {\n type: 'text';\n text: string;\n};\n\ntype LangChainMessageContentImageUrl = {\n type: 'image_url';\n image_url:\n | string\n | {\n url: string;\n detail?: LangChainImageDetail;\n };\n};\n\ntype LangChainMessageContentComplex =\n | LangChainMessageContentText\n | LangChainMessageContentImageUrl\n | (Record<string, any> & {\n type?: 'text' | 'image_url' | string;\n })\n | (Record<string, any> & {\n type?: never;\n });\n\ntype LangChainMessageContent = string | LangChainMessageContentComplex[];\n\ntype LangChainAIMessageChunk = {\n content: LangChainMessageContent;\n};\n\n// LC stream event v2\ntype LangChainStreamEvent = {\n event: string;\n data: any;\n};\n\n/**\nConverts LangChain output streams to an AI SDK Data Stream.\n\nThe following streams are supported:\n- `LangChainAIMessageChunk` streams (LangChain `model.stream` output)\n- `string` streams (LangChain `StringOutputParser` output)\n */\nexport function toDataStream(\n stream:\n | ReadableStream<LangChainStreamEvent>\n | ReadableStream<LangChainAIMessageChunk>\n | ReadableStream<string>,\n callbacks?: StreamCallbacks,\n) {\n return stream\n .pipeThrough(\n new TransformStream<\n LangChainStreamEvent | LangChainAIMessageChunk | string\n >({\n transform: async (value, controller) => {\n // text stream:\n if (typeof value === 'string') {\n controller.enqueue(value);\n return;\n }\n\n // LC stream events v2:\n if ('event' in value) {\n // chunk is AIMessage Chunk for on_chat_model_stream event:\n if (value.event === 'on_chat_model_stream') {\n forwardAIMessageChunk(\n value.data?.chunk as LangChainAIMessageChunk,\n controller,\n );\n }\n return;\n }\n\n // AI Message chunk stream:\n forwardAIMessageChunk(value, controller);\n },\n }),\n )\n .pipeThrough(createCallbacksTransformer(callbacks))\n .pipeThrough(\n new TransformStream<string, DataStreamPart>({\n transform: async (chunk, controller) => {\n controller.enqueue({ type: 'text', value: chunk });\n },\n }),\n );\n}\n\nfunction forwardAIMessageChunk(\n chunk: LangChainAIMessageChunk,\n controller: TransformStreamDefaultController<any>,\n) {\n if (typeof chunk.content === 'string') {\n controller.enqueue(chunk.content);\n } else {\n const content: LangChainMessageContentComplex[] = chunk.content;\n for (const item of content) {\n if (item.type === 'text') {\n controller.enqueue(item.text);\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,sBAA4D;AAgDrD,SAAS,aACd,QAIA,WACA;AACA,SAAO,OACJ;AAAA,IACC,IAAI,gBAEF;AAAA,MACA,WAAW,OAAO,OAAO,eAAe;AA7DhD;AA+DU,YAAI,OAAO,UAAU,UAAU;AAC7B,qBAAW,QAAQ,KAAK;AACxB;AAAA,QACF;AAGA,YAAI,WAAW,OAAO;AAEpB,cAAI,MAAM,UAAU,wBAAwB;AAC1C;AAAA,eACE,WAAM,SAAN,mBAAY;AAAA,cACZ;AAAA,YACF;AAAA,UACF;AACA;AAAA,QACF;AAGA,8BAAsB,OAAO,UAAU;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH,EACC,gBAAY,4CAA2B,SAAS,CAAC,EACjD;AAAA,IACC,IAAI,gBAAwC;AAAA,MAC1C,WAAW,OAAO,OAAO,eAAe;AACtC,mBAAW,QAAQ,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AACJ;AAEA,SAAS,sBACP,OACA,YACA;AACA,MAAI,OAAO,MAAM,YAAY,UAAU;AACrC,eAAW,QAAQ,MAAM,OAAO;AAAA,EAClC,OAAO;AACL,UAAM,UAA4C,MAAM;AACxD,eAAW,QAAQ,SAAS;AAC1B,UAAI,KAAK,SAAS,QAAQ;AACxB,mBAAW,QAAQ,KAAK,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/stream-callbacks.ts","../src/langchain-adapter.ts"],"sourcesContent":["export * from './langchain-adapter';\n","/**\n * Configuration options and helper callback methods for stream lifecycle events.\n */\nexport interface StreamCallbacks {\n /** `onStart`: Called once when the stream is initialized. */\n onStart?: () => Promise<void> | void;\n\n /** `onFinal`: Called once when the stream is closed with the final completion message. */\n onFinal?: (completion: string) => Promise<void> | void;\n\n /** `onToken`: Called for each tokenized message. */\n onToken?: (token: string) => Promise<void> | void;\n\n /** `onText`: Called for each text chunk. */\n onText?: (text: string) => Promise<void> | void;\n}\n\n/**\n * Creates a transform stream that encodes input messages and invokes optional callback functions.\n * The transform stream uses the provided callbacks to execute custom logic at different stages of the stream's lifecycle.\n * - `onStart`: Called once when the stream is initialized.\n * - `onToken`: Called for each tokenized message.\n * - `onFinal`: Called once when the stream is closed with the final completion message.\n *\n * This function is useful when you want to process a stream of messages and perform specific actions during the stream's lifecycle.\n *\n * @param {StreamCallbacks} [callbacks] - An object containing the callback functions.\n * @return {TransformStream<string, Uint8Array>} A transform stream that encodes input messages as Uint8Array and allows the execution of custom logic through callbacks.\n *\n * @example\n * const callbacks = {\n * onStart: async () => console.log('Stream started'),\n * onToken: async (token) => console.log(`Token: ${token}`),\n * onFinal: async () => data.close()\n * };\n * const transformer = createCallbacksTransformer(callbacks);\n */\nexport function createCallbacksTransformer(\n callbacks: StreamCallbacks | undefined = {},\n): TransformStream<string, string> {\n let aggregatedResponse = '';\n\n return new TransformStream({\n async start(): Promise<void> {\n if (callbacks.onStart) await callbacks.onStart();\n },\n\n async transform(message, controller): Promise<void> {\n controller.enqueue(message);\n\n aggregatedResponse += message;\n\n if (callbacks.onToken) await callbacks.onToken(message);\n if (callbacks.onText && typeof message === 'string') {\n await callbacks.onText(message);\n }\n },\n\n async flush(): Promise<void> {\n if (callbacks.onFinal) {\n await callbacks.onFinal(aggregatedResponse);\n }\n },\n });\n}\n","import { DataStreamPart } from 'ai';\nimport {\n createCallbacksTransformer,\n StreamCallbacks,\n} from './stream-callbacks';\n\ntype LangChainImageDetail = 'auto' | 'low' | 'high';\n\ntype LangChainMessageContentText = {\n type: 'text';\n text: string;\n};\n\ntype LangChainMessageContentImageUrl = {\n type: 'image_url';\n image_url:\n | string\n | {\n url: string;\n detail?: LangChainImageDetail;\n };\n};\n\ntype LangChainMessageContentComplex =\n | LangChainMessageContentText\n | LangChainMessageContentImageUrl\n | (Record<string, any> & {\n type?: 'text' | 'image_url' | string;\n })\n | (Record<string, any> & {\n type?: never;\n });\n\ntype LangChainMessageContent = string | LangChainMessageContentComplex[];\n\ntype LangChainAIMessageChunk = {\n content: LangChainMessageContent;\n};\n\n// LC stream event v2\ntype LangChainStreamEvent = {\n event: string;\n data: any;\n};\n\n/**\nConverts LangChain output streams to an AI SDK Data Stream.\n\nThe following streams are supported:\n- `LangChainAIMessageChunk` streams (LangChain `model.stream` output)\n- `string` streams (LangChain `StringOutputParser` output)\n */\nexport function toDataStream(\n stream:\n | ReadableStream<LangChainStreamEvent>\n | ReadableStream<LangChainAIMessageChunk>\n | ReadableStream<string>,\n callbacks?: StreamCallbacks,\n) {\n return stream\n .pipeThrough(\n new TransformStream<\n LangChainStreamEvent | LangChainAIMessageChunk | string\n >({\n transform: async (value, controller) => {\n // text stream:\n if (typeof value === 'string') {\n controller.enqueue(value);\n return;\n }\n\n // LC stream events v2:\n if ('event' in value) {\n // chunk is AIMessage Chunk for on_chat_model_stream event:\n if (value.event === 'on_chat_model_stream') {\n forwardAIMessageChunk(\n value.data?.chunk as LangChainAIMessageChunk,\n controller,\n );\n }\n return;\n }\n\n // AI Message chunk stream:\n forwardAIMessageChunk(value, controller);\n },\n }),\n )\n .pipeThrough(createCallbacksTransformer(callbacks))\n .pipeThrough(\n new TransformStream<string, DataStreamPart>({\n transform: async (chunk, controller) => {\n controller.enqueue({ type: 'text', value: chunk });\n },\n }),\n );\n}\n\nfunction forwardAIMessageChunk(\n chunk: LangChainAIMessageChunk,\n controller: TransformStreamDefaultController<any>,\n) {\n if (typeof chunk.content === 'string') {\n controller.enqueue(chunk.content);\n } else {\n const content: LangChainMessageContentComplex[] = chunk.content;\n for (const item of content) {\n if (item.type === 'text') {\n controller.enqueue(item.text);\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACqCO,SAAS,2BACd,YAAyC,CAAC,GACT;AACjC,MAAI,qBAAqB;AAEzB,SAAO,IAAI,gBAAgB;AAAA,IACzB,MAAM,QAAuB;AAC3B,UAAI,UAAU,QAAS,OAAM,UAAU,QAAQ;AAAA,IACjD;AAAA,IAEA,MAAM,UAAU,SAAS,YAA2B;AAClD,iBAAW,QAAQ,OAAO;AAE1B,4BAAsB;AAEtB,UAAI,UAAU,QAAS,OAAM,UAAU,QAAQ,OAAO;AACtD,UAAI,UAAU,UAAU,OAAO,YAAY,UAAU;AACnD,cAAM,UAAU,OAAO,OAAO;AAAA,MAChC;AAAA,IACF;AAAA,IAEA,MAAM,QAAuB;AAC3B,UAAI,UAAU,SAAS;AACrB,cAAM,UAAU,QAAQ,kBAAkB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACZO,SAAS,aACd,QAIA,WACA;AACA,SAAO,OACJ;AAAA,IACC,IAAI,gBAEF;AAAA,MACA,WAAW,OAAO,OAAO,eAAe;AAhEhD;AAkEU,YAAI,OAAO,UAAU,UAAU;AAC7B,qBAAW,QAAQ,KAAK;AACxB;AAAA,QACF;AAGA,YAAI,WAAW,OAAO;AAEpB,cAAI,MAAM,UAAU,wBAAwB;AAC1C;AAAA,eACE,WAAM,SAAN,mBAAY;AAAA,cACZ;AAAA,YACF;AAAA,UACF;AACA;AAAA,QACF;AAGA,8BAAsB,OAAO,UAAU;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH,EACC,YAAY,2BAA2B,SAAS,CAAC,EACjD;AAAA,IACC,IAAI,gBAAwC;AAAA,MAC1C,WAAW,OAAO,OAAO,eAAe;AACtC,mBAAW,QAAQ,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AACJ;AAEA,SAAS,sBACP,OACA,YACA;AACA,MAAI,OAAO,MAAM,YAAY,UAAU;AACrC,eAAW,QAAQ,MAAM,OAAO;AAAA,EAClC,OAAO;AACL,UAAM,UAA4C,MAAM;AACxD,eAAW,QAAQ,SAAS;AAC1B,UAAI,KAAK,SAAS,QAAQ;AACxB,mBAAW,QAAQ,KAAK,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
package/dist/index.mjs CHANGED
@@ -1,5 +1,27 @@
1
+ // src/stream-callbacks.ts
2
+ function createCallbacksTransformer(callbacks = {}) {
3
+ let aggregatedResponse = "";
4
+ return new TransformStream({
5
+ async start() {
6
+ if (callbacks.onStart) await callbacks.onStart();
7
+ },
8
+ async transform(message, controller) {
9
+ controller.enqueue(message);
10
+ aggregatedResponse += message;
11
+ if (callbacks.onToken) await callbacks.onToken(message);
12
+ if (callbacks.onText && typeof message === "string") {
13
+ await callbacks.onText(message);
14
+ }
15
+ },
16
+ async flush() {
17
+ if (callbacks.onFinal) {
18
+ await callbacks.onFinal(aggregatedResponse);
19
+ }
20
+ }
21
+ });
22
+ }
23
+
1
24
  // src/langchain-adapter.ts
2
- import { createCallbacksTransformer } from "ai/internal";
3
25
  function toDataStream(stream, callbacks) {
4
26
  return stream.pipeThrough(
5
27
  new TransformStream({
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/langchain-adapter.ts"],"sourcesContent":["import { DataStreamPart } from 'ai';\nimport { createCallbacksTransformer, StreamCallbacks } from 'ai/internal';\n\ntype LangChainImageDetail = 'auto' | 'low' | 'high';\n\ntype LangChainMessageContentText = {\n type: 'text';\n text: string;\n};\n\ntype LangChainMessageContentImageUrl = {\n type: 'image_url';\n image_url:\n | string\n | {\n url: string;\n detail?: LangChainImageDetail;\n };\n};\n\ntype LangChainMessageContentComplex =\n | LangChainMessageContentText\n | LangChainMessageContentImageUrl\n | (Record<string, any> & {\n type?: 'text' | 'image_url' | string;\n })\n | (Record<string, any> & {\n type?: never;\n });\n\ntype LangChainMessageContent = string | LangChainMessageContentComplex[];\n\ntype LangChainAIMessageChunk = {\n content: LangChainMessageContent;\n};\n\n// LC stream event v2\ntype LangChainStreamEvent = {\n event: string;\n data: any;\n};\n\n/**\nConverts LangChain output streams to an AI SDK Data Stream.\n\nThe following streams are supported:\n- `LangChainAIMessageChunk` streams (LangChain `model.stream` output)\n- `string` streams (LangChain `StringOutputParser` output)\n */\nexport function toDataStream(\n stream:\n | ReadableStream<LangChainStreamEvent>\n | ReadableStream<LangChainAIMessageChunk>\n | ReadableStream<string>,\n callbacks?: StreamCallbacks,\n) {\n return stream\n .pipeThrough(\n new TransformStream<\n LangChainStreamEvent | LangChainAIMessageChunk | string\n >({\n transform: async (value, controller) => {\n // text stream:\n if (typeof value === 'string') {\n controller.enqueue(value);\n return;\n }\n\n // LC stream events v2:\n if ('event' in value) {\n // chunk is AIMessage Chunk for on_chat_model_stream event:\n if (value.event === 'on_chat_model_stream') {\n forwardAIMessageChunk(\n value.data?.chunk as LangChainAIMessageChunk,\n controller,\n );\n }\n return;\n }\n\n // AI Message chunk stream:\n forwardAIMessageChunk(value, controller);\n },\n }),\n )\n .pipeThrough(createCallbacksTransformer(callbacks))\n .pipeThrough(\n new TransformStream<string, DataStreamPart>({\n transform: async (chunk, controller) => {\n controller.enqueue({ type: 'text', value: chunk });\n },\n }),\n );\n}\n\nfunction forwardAIMessageChunk(\n chunk: LangChainAIMessageChunk,\n controller: TransformStreamDefaultController<any>,\n) {\n if (typeof chunk.content === 'string') {\n controller.enqueue(chunk.content);\n } else {\n const content: LangChainMessageContentComplex[] = chunk.content;\n for (const item of content) {\n if (item.type === 'text') {\n controller.enqueue(item.text);\n }\n }\n }\n}\n"],"mappings":";AACA,SAAS,kCAAmD;AAgDrD,SAAS,aACd,QAIA,WACA;AACA,SAAO,OACJ;AAAA,IACC,IAAI,gBAEF;AAAA,MACA,WAAW,OAAO,OAAO,eAAe;AA7DhD;AA+DU,YAAI,OAAO,UAAU,UAAU;AAC7B,qBAAW,QAAQ,KAAK;AACxB;AAAA,QACF;AAGA,YAAI,WAAW,OAAO;AAEpB,cAAI,MAAM,UAAU,wBAAwB;AAC1C;AAAA,eACE,WAAM,SAAN,mBAAY;AAAA,cACZ;AAAA,YACF;AAAA,UACF;AACA;AAAA,QACF;AAGA,8BAAsB,OAAO,UAAU;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH,EACC,YAAY,2BAA2B,SAAS,CAAC,EACjD;AAAA,IACC,IAAI,gBAAwC;AAAA,MAC1C,WAAW,OAAO,OAAO,eAAe;AACtC,mBAAW,QAAQ,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AACJ;AAEA,SAAS,sBACP,OACA,YACA;AACA,MAAI,OAAO,MAAM,YAAY,UAAU;AACrC,eAAW,QAAQ,MAAM,OAAO;AAAA,EAClC,OAAO;AACL,UAAM,UAA4C,MAAM;AACxD,eAAW,QAAQ,SAAS;AAC1B,UAAI,KAAK,SAAS,QAAQ;AACxB,mBAAW,QAAQ,KAAK,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/stream-callbacks.ts","../src/langchain-adapter.ts"],"sourcesContent":["/**\n * Configuration options and helper callback methods for stream lifecycle events.\n */\nexport interface StreamCallbacks {\n /** `onStart`: Called once when the stream is initialized. */\n onStart?: () => Promise<void> | void;\n\n /** `onFinal`: Called once when the stream is closed with the final completion message. */\n onFinal?: (completion: string) => Promise<void> | void;\n\n /** `onToken`: Called for each tokenized message. */\n onToken?: (token: string) => Promise<void> | void;\n\n /** `onText`: Called for each text chunk. */\n onText?: (text: string) => Promise<void> | void;\n}\n\n/**\n * Creates a transform stream that encodes input messages and invokes optional callback functions.\n * The transform stream uses the provided callbacks to execute custom logic at different stages of the stream's lifecycle.\n * - `onStart`: Called once when the stream is initialized.\n * - `onToken`: Called for each tokenized message.\n * - `onFinal`: Called once when the stream is closed with the final completion message.\n *\n * This function is useful when you want to process a stream of messages and perform specific actions during the stream's lifecycle.\n *\n * @param {StreamCallbacks} [callbacks] - An object containing the callback functions.\n * @return {TransformStream<string, Uint8Array>} A transform stream that encodes input messages as Uint8Array and allows the execution of custom logic through callbacks.\n *\n * @example\n * const callbacks = {\n * onStart: async () => console.log('Stream started'),\n * onToken: async (token) => console.log(`Token: ${token}`),\n * onFinal: async () => data.close()\n * };\n * const transformer = createCallbacksTransformer(callbacks);\n */\nexport function createCallbacksTransformer(\n callbacks: StreamCallbacks | undefined = {},\n): TransformStream<string, string> {\n let aggregatedResponse = '';\n\n return new TransformStream({\n async start(): Promise<void> {\n if (callbacks.onStart) await callbacks.onStart();\n },\n\n async transform(message, controller): Promise<void> {\n controller.enqueue(message);\n\n aggregatedResponse += message;\n\n if (callbacks.onToken) await callbacks.onToken(message);\n if (callbacks.onText && typeof message === 'string') {\n await callbacks.onText(message);\n }\n },\n\n async flush(): Promise<void> {\n if (callbacks.onFinal) {\n await callbacks.onFinal(aggregatedResponse);\n }\n },\n });\n}\n","import { DataStreamPart } from 'ai';\nimport {\n createCallbacksTransformer,\n StreamCallbacks,\n} from './stream-callbacks';\n\ntype LangChainImageDetail = 'auto' | 'low' | 'high';\n\ntype LangChainMessageContentText = {\n type: 'text';\n text: string;\n};\n\ntype LangChainMessageContentImageUrl = {\n type: 'image_url';\n image_url:\n | string\n | {\n url: string;\n detail?: LangChainImageDetail;\n };\n};\n\ntype LangChainMessageContentComplex =\n | LangChainMessageContentText\n | LangChainMessageContentImageUrl\n | (Record<string, any> & {\n type?: 'text' | 'image_url' | string;\n })\n | (Record<string, any> & {\n type?: never;\n });\n\ntype LangChainMessageContent = string | LangChainMessageContentComplex[];\n\ntype LangChainAIMessageChunk = {\n content: LangChainMessageContent;\n};\n\n// LC stream event v2\ntype LangChainStreamEvent = {\n event: string;\n data: any;\n};\n\n/**\nConverts LangChain output streams to an AI SDK Data Stream.\n\nThe following streams are supported:\n- `LangChainAIMessageChunk` streams (LangChain `model.stream` output)\n- `string` streams (LangChain `StringOutputParser` output)\n */\nexport function toDataStream(\n stream:\n | ReadableStream<LangChainStreamEvent>\n | ReadableStream<LangChainAIMessageChunk>\n | ReadableStream<string>,\n callbacks?: StreamCallbacks,\n) {\n return stream\n .pipeThrough(\n new TransformStream<\n LangChainStreamEvent | LangChainAIMessageChunk | string\n >({\n transform: async (value, controller) => {\n // text stream:\n if (typeof value === 'string') {\n controller.enqueue(value);\n return;\n }\n\n // LC stream events v2:\n if ('event' in value) {\n // chunk is AIMessage Chunk for on_chat_model_stream event:\n if (value.event === 'on_chat_model_stream') {\n forwardAIMessageChunk(\n value.data?.chunk as LangChainAIMessageChunk,\n controller,\n );\n }\n return;\n }\n\n // AI Message chunk stream:\n forwardAIMessageChunk(value, controller);\n },\n }),\n )\n .pipeThrough(createCallbacksTransformer(callbacks))\n .pipeThrough(\n new TransformStream<string, DataStreamPart>({\n transform: async (chunk, controller) => {\n controller.enqueue({ type: 'text', value: chunk });\n },\n }),\n );\n}\n\nfunction forwardAIMessageChunk(\n chunk: LangChainAIMessageChunk,\n controller: TransformStreamDefaultController<any>,\n) {\n if (typeof chunk.content === 'string') {\n controller.enqueue(chunk.content);\n } else {\n const content: LangChainMessageContentComplex[] = chunk.content;\n for (const item of content) {\n if (item.type === 'text') {\n controller.enqueue(item.text);\n }\n }\n }\n}\n"],"mappings":";AAqCO,SAAS,2BACd,YAAyC,CAAC,GACT;AACjC,MAAI,qBAAqB;AAEzB,SAAO,IAAI,gBAAgB;AAAA,IACzB,MAAM,QAAuB;AAC3B,UAAI,UAAU,QAAS,OAAM,UAAU,QAAQ;AAAA,IACjD;AAAA,IAEA,MAAM,UAAU,SAAS,YAA2B;AAClD,iBAAW,QAAQ,OAAO;AAE1B,4BAAsB;AAEtB,UAAI,UAAU,QAAS,OAAM,UAAU,QAAQ,OAAO;AACtD,UAAI,UAAU,UAAU,OAAO,YAAY,UAAU;AACnD,cAAM,UAAU,OAAO,OAAO;AAAA,MAChC;AAAA,IACF;AAAA,IAEA,MAAM,QAAuB;AAC3B,UAAI,UAAU,SAAS;AACrB,cAAM,UAAU,QAAQ,kBAAkB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACZO,SAAS,aACd,QAIA,WACA;AACA,SAAO,OACJ;AAAA,IACC,IAAI,gBAEF;AAAA,MACA,WAAW,OAAO,OAAO,eAAe;AAhEhD;AAkEU,YAAI,OAAO,UAAU,UAAU;AAC7B,qBAAW,QAAQ,KAAK;AACxB;AAAA,QACF;AAGA,YAAI,WAAW,OAAO;AAEpB,cAAI,MAAM,UAAU,wBAAwB;AAC1C;AAAA,eACE,WAAM,SAAN,mBAAY;AAAA,cACZ;AAAA,YACF;AAAA,UACF;AACA;AAAA,QACF;AAGA,8BAAsB,OAAO,UAAU;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH,EACC,YAAY,2BAA2B,SAAS,CAAC,EACjD;AAAA,IACC,IAAI,gBAAwC;AAAA,MAC1C,WAAW,OAAO,OAAO,eAAe;AACtC,mBAAW,QAAQ,EAAE,MAAM,QAAQ,OAAO,MAAM,CAAC;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AACJ;AAEA,SAAS,sBACP,OACA,YACA;AACA,MAAI,OAAO,MAAM,YAAY,UAAU;AACrC,eAAW,QAAQ,MAAM,OAAO;AAAA,EAClC,OAAO;AACL,UAAM,UAA4C,MAAM;AACxD,eAAW,QAAQ,SAAS;AAC1B,UAAI,KAAK,SAAS,QAAQ;AACxB,mBAAW,QAAQ,KAAK,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/langchain",
3
- "version": "1.0.0-canary.7",
3
+ "version": "1.0.0-canary.8",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -19,8 +19,7 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "ai": "5.0.0-canary.19",
23
- "@ai-sdk/provider-utils": "3.0.0-canary.15"
22
+ "ai": "5.0.0-canary.20"
24
23
  },
25
24
  "devDependencies": {
26
25
  "@types/node": "20.17.24",