base.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Default generic "any" values are for backwards compatibility.
  2. // Replace with "string" when we are comfortable with a breaking change.
  3. import { Runnable } from "../runnables/base.js";
  4. /**
  5. * Base class for prompt templates. Exposes a format method that returns a
  6. * string prompt given a set of input values.
  7. */
  8. export class BasePromptTemplate extends Runnable {
  9. get lc_attributes() {
  10. return {
  11. partialVariables: undefined, // python doesn't support this yet
  12. };
  13. }
  14. constructor(input) {
  15. super(input);
  16. Object.defineProperty(this, "lc_serializable", {
  17. enumerable: true,
  18. configurable: true,
  19. writable: true,
  20. value: true
  21. });
  22. Object.defineProperty(this, "lc_namespace", {
  23. enumerable: true,
  24. configurable: true,
  25. writable: true,
  26. value: ["langchain_core", "prompts", this._getPromptType()]
  27. });
  28. Object.defineProperty(this, "inputVariables", {
  29. enumerable: true,
  30. configurable: true,
  31. writable: true,
  32. value: void 0
  33. });
  34. Object.defineProperty(this, "outputParser", {
  35. enumerable: true,
  36. configurable: true,
  37. writable: true,
  38. value: void 0
  39. });
  40. Object.defineProperty(this, "partialVariables", {
  41. enumerable: true,
  42. configurable: true,
  43. writable: true,
  44. value: void 0
  45. });
  46. /**
  47. * Metadata to be used for tracing.
  48. */
  49. Object.defineProperty(this, "metadata", {
  50. enumerable: true,
  51. configurable: true,
  52. writable: true,
  53. value: void 0
  54. });
  55. /** Tags to be used for tracing. */
  56. Object.defineProperty(this, "tags", {
  57. enumerable: true,
  58. configurable: true,
  59. writable: true,
  60. value: void 0
  61. });
  62. const { inputVariables } = input;
  63. if (inputVariables.includes("stop")) {
  64. throw new Error("Cannot have an input variable named 'stop', as it is used internally, please rename.");
  65. }
  66. Object.assign(this, input);
  67. }
  68. /**
  69. * Merges partial variables and user variables.
  70. * @param userVariables The user variables to merge with the partial variables.
  71. * @returns A Promise that resolves to an object containing the merged variables.
  72. */
  73. async mergePartialAndUserVariables(userVariables) {
  74. const partialVariables = this.partialVariables ?? {};
  75. const partialValues = {};
  76. for (const [key, value] of Object.entries(partialVariables)) {
  77. if (typeof value === "string") {
  78. partialValues[key] = value;
  79. }
  80. else {
  81. partialValues[key] = await value();
  82. }
  83. }
  84. const allKwargs = {
  85. ...partialValues,
  86. ...userVariables,
  87. };
  88. return allKwargs;
  89. }
  90. /**
  91. * Invokes the prompt template with the given input and options.
  92. * @param input The input to invoke the prompt template with.
  93. * @param options Optional configuration for the callback.
  94. * @returns A Promise that resolves to the output of the prompt template.
  95. */
  96. async invoke(input, options) {
  97. const metadata = {
  98. ...this.metadata,
  99. ...options?.metadata,
  100. };
  101. const tags = [...(this.tags ?? []), ...(options?.tags ?? [])];
  102. return this._callWithConfig((input) => this.formatPromptValue(input), input, { ...options, tags, metadata, runType: "prompt" });
  103. }
  104. /**
  105. * Return a json-like object representing this prompt template.
  106. * @deprecated
  107. */
  108. serialize() {
  109. throw new Error("Use .toJSON() instead");
  110. }
  111. /**
  112. * @deprecated
  113. * Load a prompt template from a json-like object describing it.
  114. *
  115. * @remarks
  116. * Deserializing needs to be async because templates (e.g. {@link FewShotPromptTemplate}) can
  117. * reference remote resources that we read asynchronously with a web
  118. * request.
  119. */
  120. static async deserialize(data) {
  121. switch (data._type) {
  122. case "prompt": {
  123. const { PromptTemplate } = await import("./prompt.js");
  124. return PromptTemplate.deserialize(data);
  125. }
  126. case undefined: {
  127. const { PromptTemplate } = await import("./prompt.js");
  128. return PromptTemplate.deserialize({ ...data, _type: "prompt" });
  129. }
  130. case "few_shot": {
  131. const { FewShotPromptTemplate } = await import("./few_shot.js");
  132. return FewShotPromptTemplate.deserialize(data);
  133. }
  134. default:
  135. throw new Error(`Invalid prompt type in config: ${data._type}`);
  136. }
  137. }
  138. }