@blaxel/langgraph 0.2.49-preview.112 → 0.2.50-dev.215

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.
@@ -14,7 +14,9 @@ const createCohereFetcher = () => {
14
14
  // Extract all fields from args
15
15
  const { url, method, headers: argsHeaders, body, contentType, queryParameters, timeoutMs, withCredentials, abortSignal, requestType, responseType, duplex } = args;
16
16
  // Build URL with query parameters
17
- let requestUrl = url;
17
+ // Rewrite /v1/chat to /v2/chat for Cohere API v2 compatibility
18
+ let requestUrl = url.replace('/v1/chat', '/v2/chat');
19
+ const isV2Endpoint = requestUrl.includes('/v2/chat');
18
20
  if (queryParameters) {
19
21
  const params = new URLSearchParams();
20
22
  Object.entries(queryParameters).forEach(([key, value]) => {
@@ -60,7 +62,40 @@ const createCohereFetcher = () => {
60
62
  let requestBody;
61
63
  if (body !== undefined) {
62
64
  if (requestType === 'json' || !requestType) {
63
- requestBody = JSON.stringify(body);
65
+ // Transform body for Cohere v2 API compatibility (only if using v2 endpoint)
66
+ let transformedBody = body;
67
+ if (isV2Endpoint && typeof body === 'object' && body !== null && !Array.isArray(body)) {
68
+ const bodyObj = body;
69
+ transformedBody = { ...bodyObj };
70
+ const transformedObj = transformedBody;
71
+ // Remove v1-only fields that are not supported in v2
72
+ const fieldsToRemove = ['chat_history'];
73
+ for (const field of fieldsToRemove) {
74
+ if (field in transformedObj) {
75
+ delete transformedObj[field];
76
+ }
77
+ }
78
+ // Convert 'message' to 'messages' format if message exists and messages doesn't
79
+ if ('message' in transformedObj && !('messages' in transformedObj)) {
80
+ const message = transformedObj.message;
81
+ if (typeof message === 'string' && message.trim().length > 0) {
82
+ // Convert single message string to messages array format
83
+ transformedObj.messages = [
84
+ {
85
+ role: 'user',
86
+ content: message,
87
+ },
88
+ ];
89
+ }
90
+ // Remove the old message field
91
+ delete transformedObj.message;
92
+ }
93
+ // Handle tool_results - v2 might use a different format, remove for now
94
+ if ('tool_results' in transformedObj) {
95
+ delete transformedObj.tool_results;
96
+ }
97
+ }
98
+ requestBody = JSON.stringify(transformedBody);
64
99
  }
65
100
  else if (requestType === 'bytes' && body instanceof Uint8Array) {
66
101
  // Create a new ArrayBuffer from the Uint8Array to avoid SharedArrayBuffer issues
@@ -73,7 +108,45 @@ const createCohereFetcher = () => {
73
108
  requestBody = body;
74
109
  }
75
110
  else if (typeof body === 'string') {
76
- requestBody = body;
111
+ // Parse and transform JSON strings (only if using v2 endpoint)
112
+ if (isV2Endpoint) {
113
+ try {
114
+ const parsed = JSON.parse(body);
115
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
116
+ const transformed = { ...parsed };
117
+ // Remove v1-only fields
118
+ if ('chat_history' in transformed) {
119
+ delete transformed.chat_history;
120
+ }
121
+ if ('tool_results' in transformed) {
122
+ delete transformed.tool_results;
123
+ }
124
+ // Convert 'message' to 'messages' format if message exists and messages doesn't
125
+ if ('message' in transformed && !('messages' in transformed)) {
126
+ const message = transformed.message;
127
+ if (typeof message === 'string' && message.trim().length > 0) {
128
+ transformed.messages = [
129
+ {
130
+ role: 'user',
131
+ content: message,
132
+ },
133
+ ];
134
+ }
135
+ delete transformed.message;
136
+ }
137
+ requestBody = JSON.stringify(transformed);
138
+ }
139
+ else {
140
+ requestBody = body;
141
+ }
142
+ }
143
+ catch {
144
+ requestBody = body;
145
+ }
146
+ }
147
+ else {
148
+ requestBody = body;
149
+ }
77
150
  }
78
151
  else {
79
152
  requestBody = JSON.stringify(body);
@@ -126,6 +199,41 @@ const createCohereFetcher = () => {
126
199
  else {
127
200
  // Default to JSON
128
201
  responseBody = await response.json();
202
+ // Transform v2 response format to v1 format for ChatCohere compatibility
203
+ if (isV2Endpoint && typeof responseBody === 'object' && responseBody !== null) {
204
+ const responseObj = responseBody;
205
+ if ('message' in responseObj && typeof responseObj.message === 'object' && responseObj.message !== null) {
206
+ const v2Message = responseObj.message;
207
+ // Extract text from content array
208
+ let text = '';
209
+ if (Array.isArray(v2Message.content)) {
210
+ const contentArray = v2Message.content;
211
+ // Find the text content block
212
+ const textBlock = contentArray.find((item) => item.type === 'text' && item.text);
213
+ if (textBlock && textBlock.text) {
214
+ text = textBlock.text;
215
+ }
216
+ else {
217
+ // Fallback: join all text-like content
218
+ text = contentArray
219
+ .map((item) => item.text || item.thinking || '')
220
+ .filter(Boolean)
221
+ .join('\n');
222
+ }
223
+ }
224
+ else if (typeof v2Message.content === 'string') {
225
+ text = v2Message.content;
226
+ }
227
+ // Transform to v1-like format that ChatCohere expects
228
+ const transformedResponse = {
229
+ ...responseObj,
230
+ text: text,
231
+ // Keep the original message structure in case ChatCohere needs it
232
+ message: responseObj.message,
233
+ };
234
+ responseBody = transformedResponse;
235
+ }
236
+ }
129
237
  }
130
238
  // Return success response in the format CohereClient expects
131
239
  return {
@@ -537,7 +537,12 @@ class ChatGoogleGenerativeAI extends chat_models_1.BaseChatModel {
537
537
  return "googlegenerativeai";
538
538
  }
539
539
  bindTools(tools, kwargs) {
540
- return this.bind({ tools: (0, tools_js_1.convertToolsToGenAI)(tools)?.tools, ...kwargs });
540
+ const convertedTools = (0, tools_js_1.convertToolsToGenAI)(tools);
541
+ const bindOptions = { tools: convertedTools?.tools, ...kwargs };
542
+ // BaseChatModel extends Runnable which has a bind method
543
+ // Access bind through unknown to satisfy TypeScript's type checking
544
+ const baseModel = this;
545
+ return baseModel.bind(bindOptions);
541
546
  }
542
547
  invocationParams(options) {
543
548
  const toolsAndConfig = options?.tools?.length
@@ -728,7 +733,8 @@ class ChatGoogleGenerativeAI extends chat_models_1.BaseChatModel {
728
733
  keyName: functionName,
729
734
  });
730
735
  }
731
- const llm = this.bind({
736
+ // @ts-ignore - bind method exists on BaseChatModel but TypeScript can't infer it
737
+ const llm = super.bind({
732
738
  tools,
733
739
  tool_choice: functionName,
734
740
  });
@@ -122,6 +122,9 @@ function convertMessageContentToParts(message, isMultimodalModel) {
122
122
  if (!isMultimodalModel) {
123
123
  throw new Error(`This model does not support images`);
124
124
  }
125
+ if (!c.image_url) {
126
+ throw new Error("Please provide image as base64 encoded data URL");
127
+ }
125
128
  let source;
126
129
  if (typeof c.image_url === "string") {
127
130
  source = c.image_url;
package/dist/cjs/model.js CHANGED
@@ -23,6 +23,24 @@ const authenticatedFetch = () => {
23
23
  ...dynamicHeaders,
24
24
  ...(init?.headers || {}),
25
25
  };
26
+ // Ensure Content-Type is set for JSON requests if body exists and Content-Type is not already set
27
+ if (init?.body && !headers['Content-Type'] && !headers['content-type']) {
28
+ // If body is an object, it will be serialized to JSON by fetch
29
+ // If body is a string, check if it looks like JSON
30
+ if (typeof init.body === 'string') {
31
+ const trimmed = init.body.trim();
32
+ if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
33
+ headers['Content-Type'] = 'application/json';
34
+ }
35
+ }
36
+ else {
37
+ // For non-string bodies (FormData, Blob, etc.), let fetch handle it
38
+ // For objects, assume JSON
39
+ if (typeof init.body === 'object' && !(init.body instanceof FormData) && !(init.body instanceof Blob)) {
40
+ headers['Content-Type'] = 'application/json';
41
+ }
42
+ }
43
+ }
26
44
  // Make the request with merged headers
27
45
  return await fetch(input, {
28
46
  ...init,
@@ -63,6 +81,11 @@ const blModel = async (model, options) => {
63
81
  });
64
82
  }
65
83
  else if (type === "cohere") {
84
+ // ChatCohere requires a custom client with fetcher for:
85
+ // 1. Dynamic authentication headers (settings.headers)
86
+ // 2. Custom environment URL (url)
87
+ // 3. URL rewriting (v1 -> v2) and body transformation for v2 compatibility
88
+ // @ts-ignore Error in langgraph
66
89
  return new cohere_1.ChatCohere({
67
90
  apiKey: "replaced",
68
91
  model: modelData?.spec?.runtime?.model,
@@ -75,6 +98,7 @@ const blModel = async (model, options) => {
75
98
  });
76
99
  }
77
100
  else if (type === "deepseek") {
101
+ // @ts-ignore Error in langgraph
78
102
  return new deepseek_1.ChatDeepSeek({
79
103
  apiKey: "replaced",
80
104
  model: modelData?.spec?.runtime?.model,
@@ -87,9 +111,11 @@ const blModel = async (model, options) => {
87
111
  });
88
112
  }
89
113
  else if (type === "anthropic") {
114
+ // @ts-ignore Error in langgraph
90
115
  return new anthropic_1.ChatAnthropic({
91
116
  anthropicApiUrl: url,
92
117
  model: modelData?.spec?.runtime?.model,
118
+ apiKey: "replaced",
93
119
  clientOptions: {
94
120
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
95
121
  fetch: authenticatedFetch(),
@@ -35,16 +35,15 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const RunnableModule = __importStar(require("@langchain/core/runnables"));
37
37
  const ToolsModule = __importStar(require("@langchain/core/tools"));
38
+ const AgentsModule = __importStar(require("@langchain/core/agents"));
38
39
  const VectorStoresModule = __importStar(require("@langchain/core/vectorstores"));
39
40
  const instrumentation_1 = require("@opentelemetry/instrumentation");
40
41
  const instrumentation_langchain_1 = require("@traceloop/instrumentation-langchain");
41
- const AgentsModule = __importStar(require("langchain/agents"));
42
- const ChainsModule = __importStar(require("langchain/chains"));
43
42
  const langchain = new instrumentation_langchain_1.LangChainInstrumentation();
44
43
  langchain.manuallyInstrument({
44
+ // @ts-ignore - Type definitions may be incorrect, but the method accepts these parameters at runtime
45
45
  runnablesModule: RunnableModule,
46
46
  toolsModule: ToolsModule,
47
- chainsModule: ChainsModule,
48
47
  agentsModule: AgentsModule,
49
48
  vectorStoreModule: VectorStoresModule,
50
49
  });
@@ -1,4 +1,5 @@
1
1
  import { Serialized } from "@langchain/core/load/serializable";
2
+ import { type LangSmithParams } from "@langchain/core/language_models/chat_models";
2
3
  import { ChatOpenAI } from "@langchain/openai";
3
4
  /**
4
5
  * Extends the ChatOpenAI class to create a ChatXAI agent with additional configurations.
@@ -37,5 +38,5 @@ export declare class ChatXAI extends ChatOpenAI {
37
38
  * @param options - Additional options for parameter retrieval.
38
39
  * @returns An object containing LangChain parameters.
39
40
  */
40
- getLsParams(options: unknown): import("@langchain/core/language_models/chat_models").LangSmithParams;
41
+ getLsParams(options: unknown): LangSmithParams;
41
42
  }
@@ -3,9 +3,13 @@ export declare function blTool(name: string, options?: ToolOptions | number): Pr
3
3
  [x: string]: any;
4
4
  }, {
5
5
  [x: string]: any;
6
- }>, any, any, unknown>[]>;
6
+ }>, unknown, {
7
+ [x: string]: any;
8
+ }, unknown>[]>;
7
9
  export declare function blTools(names: string[], ms?: number): Promise<import("@langchain/core/tools").DynamicStructuredTool<import("zod").ZodObject<any, import("zod").UnknownKeysParam, import("zod").ZodTypeAny, {
8
10
  [x: string]: any;
9
11
  }, {
10
12
  [x: string]: any;
11
- }>, any, any, unknown>[]>;
13
+ }>, unknown, {
14
+ [x: string]: any;
15
+ }, unknown>[]>;