langchain 0.0.186 → 0.0.188

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 (49) hide show
  1. package/dist/callbacks/handlers/llmonitor.cjs +31 -17
  2. package/dist/callbacks/handlers/llmonitor.js +31 -17
  3. package/dist/chat_models/bedrock/web.cjs +5 -3
  4. package/dist/chat_models/bedrock/web.js +5 -3
  5. package/dist/embeddings/cohere.cjs +18 -9
  6. package/dist/embeddings/cohere.d.ts +13 -1
  7. package/dist/embeddings/cohere.js +18 -9
  8. package/dist/experimental/chat_models/ollama_functions.cjs +140 -0
  9. package/dist/experimental/chat_models/ollama_functions.d.ts +76 -0
  10. package/dist/experimental/chat_models/ollama_functions.js +136 -0
  11. package/dist/llms/bedrock/web.cjs +5 -3
  12. package/dist/llms/bedrock/web.js +5 -3
  13. package/dist/llms/cohere.cjs +9 -7
  14. package/dist/llms/cohere.d.ts +1 -1
  15. package/dist/llms/cohere.js +9 -7
  16. package/dist/load/import_map.cjs +3 -1
  17. package/dist/load/import_map.d.ts +1 -0
  18. package/dist/load/import_map.js +1 -0
  19. package/dist/memory/buffer_token_memory.cjs +92 -0
  20. package/dist/memory/buffer_token_memory.d.ts +41 -0
  21. package/dist/memory/buffer_token_memory.js +88 -0
  22. package/dist/memory/index.cjs +3 -1
  23. package/dist/memory/index.d.ts +1 -0
  24. package/dist/memory/index.js +1 -0
  25. package/dist/output_parsers/http_response.cjs +82 -0
  26. package/dist/output_parsers/http_response.d.ts +28 -0
  27. package/dist/output_parsers/http_response.js +78 -0
  28. package/dist/output_parsers/index.cjs +3 -1
  29. package/dist/output_parsers/index.d.ts +1 -0
  30. package/dist/output_parsers/index.js +1 -0
  31. package/dist/output_parsers/openai_functions.cjs +4 -6
  32. package/dist/output_parsers/openai_functions.d.ts +1 -1
  33. package/dist/output_parsers/openai_functions.js +4 -6
  34. package/dist/prompts/base.cjs +1 -1
  35. package/dist/prompts/base.js +1 -1
  36. package/dist/schema/index.cjs +2 -2
  37. package/dist/schema/index.d.ts +2 -2
  38. package/dist/schema/index.js +2 -2
  39. package/dist/schema/output_parser.d.ts +2 -2
  40. package/dist/util/bedrock.cjs +8 -0
  41. package/dist/util/bedrock.js +8 -0
  42. package/dist/util/ollama.cjs +10 -12
  43. package/dist/util/ollama.js +10 -12
  44. package/dist/util/openapi.cjs +5 -2
  45. package/dist/util/openapi.js +5 -2
  46. package/experimental/chat_models/ollama_functions.cjs +1 -0
  47. package/experimental/chat_models/ollama_functions.d.ts +1 -0
  48. package/experimental/chat_models/ollama_functions.js +1 -0
  49. package/package.json +16 -6
@@ -19,8 +19,19 @@ const parseRole = (id) => {
19
19
  return "ai";
20
20
  if (roleHint.includes("Function"))
21
21
  return "function";
22
+ if (roleHint.includes("Tool"))
23
+ return "tool";
22
24
  return "ai";
23
25
  };
26
+ const PARAMS_TO_CAPTURE = [
27
+ "stop",
28
+ "stop_sequences",
29
+ "function_call",
30
+ "functions",
31
+ "tools",
32
+ "tool_choice",
33
+ "response_format",
34
+ ];
24
35
  const convertToLLMonitorMessages = (input) => {
25
36
  const parseMessage = (raw) => {
26
37
  if (typeof raw === "string")
@@ -35,11 +46,10 @@ const convertToLLMonitorMessages = (input) => {
35
46
  const role = parseRole(message.id);
36
47
  const obj = message.kwargs;
37
48
  const text = message.text ?? obj.content;
38
- const functionCall = obj.additional_kwargs?.function_call;
39
49
  return {
40
50
  role,
41
51
  text,
42
- functionCall,
52
+ ...(obj.additional_kwargs ?? {}),
43
53
  };
44
54
  }
45
55
  catch (e) {
@@ -83,6 +93,21 @@ const parseOutput = (rawOutput) => {
83
93
  return result;
84
94
  return rawOutput;
85
95
  };
96
+ const parseExtraAndName = (llm, extraParams, metadata) => {
97
+ const params = {
98
+ ...(extraParams?.invocation_params ?? {}),
99
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
100
+ // @ts-ignore this is a valid property
101
+ ...(llm?.kwargs ?? {}),
102
+ ...(metadata || {}),
103
+ };
104
+ const { model, model_name, modelName, model_id, userId, userProps, ...rest } = params;
105
+ const name = model || modelName || model_name || model_id || llm.id.at(-1);
106
+ // Filter rest to only include params we want to capture
107
+ const extra = Object.fromEntries(Object.entries(rest).filter(([key]) => PARAMS_TO_CAPTURE.includes(key) ||
108
+ ["string", "number", "boolean"].includes(typeof rest[key])));
109
+ return { name, extra, userId, userProps };
110
+ };
86
111
  class LLMonitorHandler extends base_js_1.BaseCallbackHandler {
87
112
  constructor(fields = {}) {
88
113
  super(fields);
@@ -109,18 +134,13 @@ class LLMonitorHandler extends base_js_1.BaseCallbackHandler {
109
134
  }
110
135
  }
111
136
  async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata) {
112
- const params = {
113
- ...(extraParams?.invocation_params || {}),
114
- ...(metadata || {}),
115
- };
116
- const { model, model_name, modelName, userId, userProps, ...rest } = params;
117
- const name = model || modelName || model_name || llm.id.at(-1);
137
+ const { name, extra, userId, userProps } = parseExtraAndName(llm, extraParams, metadata);
118
138
  await this.monitor.trackEvent("llm", "start", {
119
139
  runId,
120
140
  parentRunId,
121
141
  name,
122
142
  input: (0, exports.convertToLLMonitorMessages)(prompts),
123
- extra: rest,
143
+ extra,
124
144
  userId,
125
145
  userProps,
126
146
  tags,
@@ -128,19 +148,13 @@ class LLMonitorHandler extends base_js_1.BaseCallbackHandler {
128
148
  });
129
149
  }
130
150
  async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata) {
131
- const params = {
132
- ...(extraParams?.invocation_params || {}),
133
- ...(metadata || {}),
134
- };
135
- // Expand them so they're excluded from the "extra" field
136
- const { model, model_name, modelName, userId, userProps, ...rest } = params;
137
- const name = model || modelName || model_name || llm.id.at(-1);
151
+ const { name, extra, userId, userProps } = parseExtraAndName(llm, extraParams, metadata);
138
152
  await this.monitor.trackEvent("llm", "start", {
139
153
  runId,
140
154
  parentRunId,
141
155
  name,
142
156
  input: (0, exports.convertToLLMonitorMessages)(messages),
143
- extra: rest,
157
+ extra,
144
158
  userId,
145
159
  userProps,
146
160
  tags,
@@ -13,8 +13,19 @@ const parseRole = (id) => {
13
13
  return "ai";
14
14
  if (roleHint.includes("Function"))
15
15
  return "function";
16
+ if (roleHint.includes("Tool"))
17
+ return "tool";
16
18
  return "ai";
17
19
  };
20
+ const PARAMS_TO_CAPTURE = [
21
+ "stop",
22
+ "stop_sequences",
23
+ "function_call",
24
+ "functions",
25
+ "tools",
26
+ "tool_choice",
27
+ "response_format",
28
+ ];
18
29
  export const convertToLLMonitorMessages = (input) => {
19
30
  const parseMessage = (raw) => {
20
31
  if (typeof raw === "string")
@@ -29,11 +40,10 @@ export const convertToLLMonitorMessages = (input) => {
29
40
  const role = parseRole(message.id);
30
41
  const obj = message.kwargs;
31
42
  const text = message.text ?? obj.content;
32
- const functionCall = obj.additional_kwargs?.function_call;
33
43
  return {
34
44
  role,
35
45
  text,
36
- functionCall,
46
+ ...(obj.additional_kwargs ?? {}),
37
47
  };
38
48
  }
39
49
  catch (e) {
@@ -76,6 +86,21 @@ const parseOutput = (rawOutput) => {
76
86
  return result;
77
87
  return rawOutput;
78
88
  };
89
+ const parseExtraAndName = (llm, extraParams, metadata) => {
90
+ const params = {
91
+ ...(extraParams?.invocation_params ?? {}),
92
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
93
+ // @ts-ignore this is a valid property
94
+ ...(llm?.kwargs ?? {}),
95
+ ...(metadata || {}),
96
+ };
97
+ const { model, model_name, modelName, model_id, userId, userProps, ...rest } = params;
98
+ const name = model || modelName || model_name || model_id || llm.id.at(-1);
99
+ // Filter rest to only include params we want to capture
100
+ const extra = Object.fromEntries(Object.entries(rest).filter(([key]) => PARAMS_TO_CAPTURE.includes(key) ||
101
+ ["string", "number", "boolean"].includes(typeof rest[key])));
102
+ return { name, extra, userId, userProps };
103
+ };
79
104
  export class LLMonitorHandler extends BaseCallbackHandler {
80
105
  constructor(fields = {}) {
81
106
  super(fields);
@@ -102,18 +127,13 @@ export class LLMonitorHandler extends BaseCallbackHandler {
102
127
  }
103
128
  }
104
129
  async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata) {
105
- const params = {
106
- ...(extraParams?.invocation_params || {}),
107
- ...(metadata || {}),
108
- };
109
- const { model, model_name, modelName, userId, userProps, ...rest } = params;
110
- const name = model || modelName || model_name || llm.id.at(-1);
130
+ const { name, extra, userId, userProps } = parseExtraAndName(llm, extraParams, metadata);
111
131
  await this.monitor.trackEvent("llm", "start", {
112
132
  runId,
113
133
  parentRunId,
114
134
  name,
115
135
  input: convertToLLMonitorMessages(prompts),
116
- extra: rest,
136
+ extra,
117
137
  userId,
118
138
  userProps,
119
139
  tags,
@@ -121,19 +141,13 @@ export class LLMonitorHandler extends BaseCallbackHandler {
121
141
  });
122
142
  }
123
143
  async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata) {
124
- const params = {
125
- ...(extraParams?.invocation_params || {}),
126
- ...(metadata || {}),
127
- };
128
- // Expand them so they're excluded from the "extra" field
129
- const { model, model_name, modelName, userId, userProps, ...rest } = params;
130
- const name = model || modelName || model_name || llm.id.at(-1);
144
+ const { name, extra, userId, userProps } = parseExtraAndName(llm, extraParams, metadata);
131
145
  await this.monitor.trackEvent("llm", "start", {
132
146
  runId,
133
147
  parentRunId,
134
148
  name,
135
149
  input: convertToLLMonitorMessages(messages),
136
- extra: rest,
150
+ extra,
137
151
  userId,
138
152
  userProps,
139
153
  tags,
@@ -158,7 +158,7 @@ class BedrockChat extends base_js_1.SimpleChatModel {
158
158
  value: true
159
159
  });
160
160
  this.model = fields?.model ?? this.model;
161
- const allowedModels = ["ai21", "anthropic", "amazon", "cohere"];
161
+ const allowedModels = ["ai21", "anthropic", "amazon", "cohere", "meta"];
162
162
  if (!allowedModels.includes(this.model.split(".")[0])) {
163
163
  throw new Error(`Unknown model: '${this.model}', only these are supported: ${allowedModels}`);
164
164
  }
@@ -260,7 +260,7 @@ class BedrockChat extends base_js_1.SimpleChatModel {
260
260
  const provider = this.model.split(".")[0];
261
261
  const service = "bedrock-runtime";
262
262
  const endpointHost = this.endpointHost ?? `${service}.${this.region}.amazonaws.com`;
263
- const bedrockMethod = provider === "anthropic" || provider === "cohere"
263
+ const bedrockMethod = provider === "anthropic" || provider === "cohere" || provider === "meta"
264
264
  ? "invoke-with-response-stream"
265
265
  : "invoke";
266
266
  const response = await this._signedFetch(messages, options, {
@@ -271,7 +271,9 @@ class BedrockChat extends base_js_1.SimpleChatModel {
271
271
  if (response.status < 200 || response.status >= 300) {
272
272
  throw Error(`Failed to access underlying url '${endpointHost}': got ${response.status} ${response.statusText}: ${await response.text()}`);
273
273
  }
274
- if (provider === "anthropic" || provider === "cohere") {
274
+ if (provider === "anthropic" ||
275
+ provider === "cohere" ||
276
+ provider === "meta") {
275
277
  const reader = response.body?.getReader();
276
278
  const decoder = new TextDecoder();
277
279
  for await (const chunk of this._readChunks(reader)) {
@@ -153,7 +153,7 @@ export class BedrockChat extends SimpleChatModel {
153
153
  value: true
154
154
  });
155
155
  this.model = fields?.model ?? this.model;
156
- const allowedModels = ["ai21", "anthropic", "amazon", "cohere"];
156
+ const allowedModels = ["ai21", "anthropic", "amazon", "cohere", "meta"];
157
157
  if (!allowedModels.includes(this.model.split(".")[0])) {
158
158
  throw new Error(`Unknown model: '${this.model}', only these are supported: ${allowedModels}`);
159
159
  }
@@ -255,7 +255,7 @@ export class BedrockChat extends SimpleChatModel {
255
255
  const provider = this.model.split(".")[0];
256
256
  const service = "bedrock-runtime";
257
257
  const endpointHost = this.endpointHost ?? `${service}.${this.region}.amazonaws.com`;
258
- const bedrockMethod = provider === "anthropic" || provider === "cohere"
258
+ const bedrockMethod = provider === "anthropic" || provider === "cohere" || provider === "meta"
259
259
  ? "invoke-with-response-stream"
260
260
  : "invoke";
261
261
  const response = await this._signedFetch(messages, options, {
@@ -266,7 +266,9 @@ export class BedrockChat extends SimpleChatModel {
266
266
  if (response.status < 200 || response.status >= 300) {
267
267
  throw Error(`Failed to access underlying url '${endpointHost}': got ${response.status} ${response.statusText}: ${await response.text()}`);
268
268
  }
269
- if (provider === "anthropic" || provider === "cohere") {
269
+ if (provider === "anthropic" ||
270
+ provider === "cohere" ||
271
+ provider === "meta") {
270
272
  const reader = response.body?.getReader();
271
273
  const decoder = new TextDecoder();
272
274
  for await (const chunk of this._readChunks(reader)) {
@@ -27,6 +27,12 @@ class CohereEmbeddings extends base_js_1.Embeddings {
27
27
  writable: true,
28
28
  value: 48
29
29
  });
30
+ Object.defineProperty(this, "inputType", {
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true,
34
+ value: void 0
35
+ });
30
36
  Object.defineProperty(this, "apiKey", {
31
37
  enumerable: true,
32
38
  configurable: true,
@@ -45,6 +51,7 @@ class CohereEmbeddings extends base_js_1.Embeddings {
45
51
  }
46
52
  this.modelName = fieldsWithDefaults?.modelName ?? this.modelName;
47
53
  this.batchSize = fieldsWithDefaults?.batchSize ?? this.batchSize;
54
+ this.inputType = fieldsWithDefaults?.inputType;
48
55
  this.apiKey = apiKey;
49
56
  }
50
57
  /**
@@ -58,14 +65,15 @@ class CohereEmbeddings extends base_js_1.Embeddings {
58
65
  const batchRequests = batches.map((batch) => this.embeddingWithRetry({
59
66
  model: this.modelName,
60
67
  texts: batch,
68
+ inputType: this.inputType,
61
69
  }));
62
70
  const batchResponses = await Promise.all(batchRequests);
63
71
  const embeddings = [];
64
72
  for (let i = 0; i < batchResponses.length; i += 1) {
65
73
  const batch = batches[i];
66
- const { body: batchResponse } = batchResponses[i];
74
+ const { embeddings: batchResponse } = batchResponses[i];
67
75
  for (let j = 0; j < batch.length; j += 1) {
68
- embeddings.push(batchResponse.embeddings[j]);
76
+ embeddings.push(batchResponse[j]);
69
77
  }
70
78
  }
71
79
  return embeddings;
@@ -77,11 +85,11 @@ class CohereEmbeddings extends base_js_1.Embeddings {
77
85
  */
78
86
  async embedQuery(text) {
79
87
  await this.maybeInitClient();
80
- const { body } = await this.embeddingWithRetry({
88
+ const { embeddings } = await this.embeddingWithRetry({
81
89
  model: this.modelName,
82
90
  texts: [text],
83
91
  });
84
- return body.embeddings[0];
92
+ return embeddings[0];
85
93
  }
86
94
  /**
87
95
  * Generates embeddings with retry capabilities.
@@ -97,16 +105,17 @@ class CohereEmbeddings extends base_js_1.Embeddings {
97
105
  */
98
106
  async maybeInitClient() {
99
107
  if (!this.client) {
100
- const { cohere } = await CohereEmbeddings.imports();
101
- this.client = cohere;
102
- this.client.init(this.apiKey);
108
+ const { CohereClient } = await CohereEmbeddings.imports();
109
+ this.client = new CohereClient({
110
+ token: this.apiKey,
111
+ });
103
112
  }
104
113
  }
105
114
  /** @ignore */
106
115
  static async imports() {
107
116
  try {
108
- const { default: cohere } = await import("cohere-ai");
109
- return { cohere };
117
+ const { CohereClient } = await import("cohere-ai");
118
+ return { CohereClient };
110
119
  }
111
120
  catch (e) {
112
121
  throw new Error("Please install cohere-ai as a dependency with, e.g. `yarn add cohere-ai`");
@@ -10,6 +10,17 @@ export interface CohereEmbeddingsParams extends EmbeddingsParams {
10
10
  * limited by the Cohere API to a maximum of 96.
11
11
  */
12
12
  batchSize?: number;
13
+ /**
14
+ * Specifies the type of input you're giving to the model.
15
+ * Not required for older versions of the embedding models (i.e. anything lower than v3),
16
+ * but is required for more recent versions (i.e. anything bigger than v2).
17
+ *
18
+ * * `search_document` - Use this when you encode documents for embeddings that you store in a vector database for search use-cases.
19
+ * * `search_query` - Use this when you query your vector DB to find relevant documents.
20
+ * * `classification` - Use this when you use the embeddings as an input to a text classifier.
21
+ * * `clustering` - Use this when you want to cluster the embeddings.
22
+ */
23
+ inputType?: string;
13
24
  }
14
25
  /**
15
26
  * A class for generating embeddings using the Cohere API.
@@ -17,6 +28,7 @@ export interface CohereEmbeddingsParams extends EmbeddingsParams {
17
28
  export declare class CohereEmbeddings extends Embeddings implements CohereEmbeddingsParams {
18
29
  modelName: string;
19
30
  batchSize: number;
31
+ inputType: string | undefined;
20
32
  private apiKey;
21
33
  private client;
22
34
  /**
@@ -51,6 +63,6 @@ export declare class CohereEmbeddings extends Embeddings implements CohereEmbedd
51
63
  private maybeInitClient;
52
64
  /** @ignore */
53
65
  static imports(): Promise<{
54
- cohere: typeof import("cohere-ai");
66
+ CohereClient: typeof import("cohere-ai").CohereClient;
55
67
  }>;
56
68
  }
@@ -24,6 +24,12 @@ export class CohereEmbeddings extends Embeddings {
24
24
  writable: true,
25
25
  value: 48
26
26
  });
27
+ Object.defineProperty(this, "inputType", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: void 0
32
+ });
27
33
  Object.defineProperty(this, "apiKey", {
28
34
  enumerable: true,
29
35
  configurable: true,
@@ -42,6 +48,7 @@ export class CohereEmbeddings extends Embeddings {
42
48
  }
43
49
  this.modelName = fieldsWithDefaults?.modelName ?? this.modelName;
44
50
  this.batchSize = fieldsWithDefaults?.batchSize ?? this.batchSize;
51
+ this.inputType = fieldsWithDefaults?.inputType;
45
52
  this.apiKey = apiKey;
46
53
  }
47
54
  /**
@@ -55,14 +62,15 @@ export class CohereEmbeddings extends Embeddings {
55
62
  const batchRequests = batches.map((batch) => this.embeddingWithRetry({
56
63
  model: this.modelName,
57
64
  texts: batch,
65
+ inputType: this.inputType,
58
66
  }));
59
67
  const batchResponses = await Promise.all(batchRequests);
60
68
  const embeddings = [];
61
69
  for (let i = 0; i < batchResponses.length; i += 1) {
62
70
  const batch = batches[i];
63
- const { body: batchResponse } = batchResponses[i];
71
+ const { embeddings: batchResponse } = batchResponses[i];
64
72
  for (let j = 0; j < batch.length; j += 1) {
65
- embeddings.push(batchResponse.embeddings[j]);
73
+ embeddings.push(batchResponse[j]);
66
74
  }
67
75
  }
68
76
  return embeddings;
@@ -74,11 +82,11 @@ export class CohereEmbeddings extends Embeddings {
74
82
  */
75
83
  async embedQuery(text) {
76
84
  await this.maybeInitClient();
77
- const { body } = await this.embeddingWithRetry({
85
+ const { embeddings } = await this.embeddingWithRetry({
78
86
  model: this.modelName,
79
87
  texts: [text],
80
88
  });
81
- return body.embeddings[0];
89
+ return embeddings[0];
82
90
  }
83
91
  /**
84
92
  * Generates embeddings with retry capabilities.
@@ -94,16 +102,17 @@ export class CohereEmbeddings extends Embeddings {
94
102
  */
95
103
  async maybeInitClient() {
96
104
  if (!this.client) {
97
- const { cohere } = await CohereEmbeddings.imports();
98
- this.client = cohere;
99
- this.client.init(this.apiKey);
105
+ const { CohereClient } = await CohereEmbeddings.imports();
106
+ this.client = new CohereClient({
107
+ token: this.apiKey,
108
+ });
100
109
  }
101
110
  }
102
111
  /** @ignore */
103
112
  static async imports() {
104
113
  try {
105
- const { default: cohere } = await import("cohere-ai");
106
- return { cohere };
114
+ const { CohereClient } = await import("cohere-ai");
115
+ return { CohereClient };
107
116
  }
108
117
  catch (e) {
109
118
  throw new Error("Please install cohere-ai as a dependency with, e.g. `yarn add cohere-ai`");
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OllamaFunctions = void 0;
4
+ const base_js_1 = require("../../chat_models/base.cjs");
5
+ const index_js_1 = require("../../schema/index.cjs");
6
+ const ollama_js_1 = require("../../chat_models/ollama.cjs");
7
+ const prompt_js_1 = require("../../prompts/prompt.cjs");
8
+ const TOOL_SYSTEM_PROMPT =
9
+ /* #__PURE__ */
10
+ prompt_js_1.PromptTemplate.fromTemplate(`You have access to the following tools:
11
+
12
+ {tools}
13
+
14
+ To use a tool, respond with a JSON object with the following structure:
15
+ {{
16
+ "tool": <name of the called tool>,
17
+ "tool_input": <parameters for the tool matching the above JSON schema>
18
+ }}`);
19
+ class OllamaFunctions extends base_js_1.BaseChatModel {
20
+ static lc_name() {
21
+ return "OllamaFunctions";
22
+ }
23
+ constructor(fields) {
24
+ super(fields ?? {});
25
+ Object.defineProperty(this, "llm", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: void 0
30
+ });
31
+ Object.defineProperty(this, "toolSystemPrompt", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: TOOL_SYSTEM_PROMPT
36
+ });
37
+ Object.defineProperty(this, "defaultResponseFunction", {
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true,
41
+ value: {
42
+ name: "__conversational_response",
43
+ description: "Respond conversationally if no other tools should be called for a given query.",
44
+ parameters: {
45
+ type: "object",
46
+ properties: {
47
+ response: {
48
+ type: "string",
49
+ description: "Conversational response to the user.",
50
+ },
51
+ },
52
+ required: ["response"],
53
+ },
54
+ }
55
+ });
56
+ Object.defineProperty(this, "lc_namespace", {
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true,
60
+ value: ["langchain", "experimental", "chat_models"]
61
+ });
62
+ this.llm = fields?.llm ?? new ollama_js_1.ChatOllama({ ...fields, format: "json" });
63
+ this.toolSystemPrompt = fields?.toolSystemPrompt ?? this.toolSystemPrompt;
64
+ }
65
+ invocationParams() {
66
+ return this.llm.invocationParams();
67
+ }
68
+ /** @ignore */
69
+ _identifyingParams() {
70
+ return this.llm._identifyingParams();
71
+ }
72
+ async _generate(messages, options, runManager) {
73
+ let functions = options.functions ?? [];
74
+ if (options.function_call !== undefined) {
75
+ functions = functions.filter((fn) => fn.name === options.function_call?.name);
76
+ if (!functions.length) {
77
+ throw new Error(`If "function_call" is specified, you must also pass a matching function in "functions".`);
78
+ }
79
+ }
80
+ else if (functions.length === 0) {
81
+ functions.push(this.defaultResponseFunction);
82
+ }
83
+ const defaultContent = await this.toolSystemPrompt.format({
84
+ tools: JSON.stringify(functions, null, 2),
85
+ });
86
+ const systemMessage = new index_js_1.SystemMessage({ content: defaultContent });
87
+ const chatResult = await this.llm._generate([systemMessage, ...messages], options, runManager);
88
+ const chatGenerationContent = chatResult.generations[0].message.content;
89
+ if (typeof chatGenerationContent !== "string") {
90
+ throw new Error("OllamaFunctions does not support non-string output.");
91
+ }
92
+ let parsedChatResult;
93
+ try {
94
+ parsedChatResult = JSON.parse(chatGenerationContent);
95
+ }
96
+ catch (e) {
97
+ throw new Error(`"${this.llm.model}" did not respond with valid JSON. Please try again.`);
98
+ }
99
+ const calledToolName = parsedChatResult.tool;
100
+ const calledToolArguments = parsedChatResult.tool_input;
101
+ const calledTool = functions.find((fn) => fn.name === calledToolName);
102
+ if (calledTool === undefined) {
103
+ throw new Error(`Failed to parse a function call from ${this.llm.model} output: ${chatGenerationContent}`);
104
+ }
105
+ if (calledTool.name === this.defaultResponseFunction.name) {
106
+ return {
107
+ generations: [
108
+ {
109
+ message: new index_js_1.AIMessage({
110
+ content: calledToolArguments.response,
111
+ }),
112
+ text: calledToolArguments.response,
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ const responseMessageWithFunctions = new index_js_1.AIMessage({
118
+ content: "",
119
+ additional_kwargs: {
120
+ function_call: {
121
+ name: calledToolName,
122
+ arguments: calledToolArguments
123
+ ? JSON.stringify(calledToolArguments)
124
+ : "",
125
+ },
126
+ },
127
+ });
128
+ return {
129
+ generations: [{ message: responseMessageWithFunctions, text: "" }],
130
+ };
131
+ }
132
+ _llmType() {
133
+ return "ollama_functions";
134
+ }
135
+ /** @ignore */
136
+ _combineLLMOutput() {
137
+ return [];
138
+ }
139
+ }
140
+ exports.OllamaFunctions = OllamaFunctions;
@@ -0,0 +1,76 @@
1
+ import { BaseChatModel, BaseChatModelParams } from "../../chat_models/base.js";
2
+ import { CallbackManagerForLLMRun } from "../../callbacks/manager.js";
3
+ import { BaseMessage, ChatResult } from "../../schema/index.js";
4
+ import { ChatOllama } from "../../chat_models/ollama.js";
5
+ import { OllamaInput } from "../../util/ollama.js";
6
+ import { BaseFunctionCallOptions } from "../../base_language/index.js";
7
+ import type { BasePromptTemplate } from "../../prompts/base.js";
8
+ export interface ChatOllamaFunctionsCallOptions extends BaseFunctionCallOptions {
9
+ }
10
+ export type OllamaFunctionsInput = Partial<OllamaInput> & BaseChatModelParams & {
11
+ llm?: ChatOllama;
12
+ toolSystemPrompt?: BasePromptTemplate;
13
+ };
14
+ export declare class OllamaFunctions extends BaseChatModel<ChatOllamaFunctionsCallOptions> {
15
+ llm: ChatOllama;
16
+ toolSystemPrompt: BasePromptTemplate;
17
+ protected defaultResponseFunction: {
18
+ name: string;
19
+ description: string;
20
+ parameters: {
21
+ type: string;
22
+ properties: {
23
+ response: {
24
+ type: string;
25
+ description: string;
26
+ };
27
+ };
28
+ required: string[];
29
+ };
30
+ };
31
+ lc_namespace: string[];
32
+ static lc_name(): string;
33
+ constructor(fields?: OllamaFunctionsInput);
34
+ invocationParams(): {
35
+ model: string;
36
+ format: import("../../util/types.js").StringWithAutocomplete<"json"> | undefined;
37
+ options: {
38
+ embedding_only: boolean | undefined;
39
+ f16_kv: boolean | undefined;
40
+ frequency_penalty: number | undefined;
41
+ logits_all: boolean | undefined;
42
+ low_vram: boolean | undefined;
43
+ main_gpu: number | undefined;
44
+ mirostat: number | undefined;
45
+ mirostat_eta: number | undefined;
46
+ mirostat_tau: number | undefined;
47
+ num_batch: number | undefined;
48
+ num_ctx: number | undefined;
49
+ num_gpu: number | undefined;
50
+ num_gqa: number | undefined;
51
+ num_keep: number | undefined;
52
+ num_thread: number | undefined;
53
+ penalize_newline: boolean | undefined;
54
+ presence_penalty: number | undefined;
55
+ repeat_last_n: number | undefined;
56
+ repeat_penalty: number | undefined;
57
+ rope_frequency_base: number | undefined;
58
+ rope_frequency_scale: number | undefined;
59
+ temperature: number | undefined;
60
+ stop: string[] | undefined;
61
+ tfs_z: number | undefined;
62
+ top_k: number | undefined;
63
+ top_p: number | undefined;
64
+ typical_p: number | undefined; /** @ignore */
65
+ use_mlock: boolean | undefined;
66
+ use_mmap: boolean | undefined;
67
+ vocab_only: boolean | undefined;
68
+ };
69
+ };
70
+ /** @ignore */
71
+ _identifyingParams(): Record<string, any>;
72
+ _generate(messages: BaseMessage[], options: this["ParsedCallOptions"], runManager?: CallbackManagerForLLMRun | undefined): Promise<ChatResult>;
73
+ _llmType(): string;
74
+ /** @ignore */
75
+ _combineLLMOutput(): never[];
76
+ }