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