{"version":3,"file":"generative_agent.cjs","names":["BaseChain","LLMChain","PromptTemplate"],"sources":["../../../src/experimental/generative_agents/generative_agent.ts"],"sourcesContent":["import type { BaseLanguageModelInterface } from \"@langchain/core/language_models/base\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport {\n  CallbackManagerForChainRun,\n  Callbacks,\n} from \"@langchain/core/callbacks/manager\";\nimport { LLMChain } from \"../../chains/llm_chain.js\";\nimport { GenerativeAgentMemory } from \"./generative_agent_memory.js\";\nimport { BaseChain } from \"../../chains/base.js\";\n\n/**\n * Configuration for the GenerativeAgent class. Defines the character's\n * name, optional age, permanent traits, status, verbosity, and summary\n * refresh seconds.\n */\nexport type GenerativeAgentConfig = {\n  name: string;\n  age?: number;\n  traits: string;\n  status: string;\n  verbose?: boolean;\n  summaryRefreshSeconds?: number;\n  // dailySummaries?: string[];\n};\n\n/**\n * Implementation of a generative agent that can learn and form new memories over\n * time. It extends the BaseChain class, which is a generic\n * sequence of calls to components, including other chains.\n * @example\n * ```typescript\n * const tommie: GenerativeAgent = new GenerativeAgent(\n *   new OpenAI({ temperature: 0.9, maxTokens: 1500 }),\n *   new GenerativeAgentMemory(\n *     new ChatOpenAI({ model: \"gpt-4o-mini\" }),\n *     new TimeWeightedVectorStoreRetriever({\n *       vectorStore: new MemoryVectorStore(new OpenAIEmbeddings()),\n *       otherScoreKeys: [\"importance\"],\n *       k: 15,\n *     }),\n *     { reflectionThreshold: 8 },\n *   ),\n *   {\n *     name: \"Tommie\",\n *     age: 25,\n *     traits: \"anxious, likes design, talkative\",\n *     status: \"looking for a job\",\n *   },\n * );\n *\n * await tommie.addMemory(\n *   \"Tommie remembers his dog, Bruno, from when he was a kid\",\n *   new Date(),\n * );\n * const summary = await tommie.getSummary({ forceRefresh: true });\n * const response = await tommie.generateDialogueResponse(\n *   \"USER says Hello Tommie, how are you today?\",\n * );\n * ```\n */\nexport class GenerativeAgent extends BaseChain {\n  static lc_name() {\n    return \"GenerativeAgent\";\n  }\n\n  // a character with memory and innate characterisitics\n  name: string; // the character's name\n\n  age?: number; // the optional age of the character\n\n  traits: string; // permanent traits to ascribe to the character\n\n  status: string; // the traits of the character you wish not to change\n\n  longTermMemory: GenerativeAgentMemory;\n\n  llm: BaseLanguageModelInterface; // the underlying language model\n\n  verbose: boolean; // false\n\n  private summary: string; // stateful self-summary generated via reflection on the character's memory.\n\n  private summaryRefreshSeconds = 3600;\n\n  private lastRefreshed: Date; // the last time the character's summary was regenerated\n\n  // TODO: Add support for daily summaries\n  // private dailySummaries: string[] = []; // summary of the events in the plan that the agent took.\n\n  _chainType(): string {\n    return \"generative_agent_executor\";\n  }\n\n  get inputKeys(): string[] {\n    return [\"observation\", \"suffix\", \"now\"];\n  }\n\n  get outputKeys(): string[] {\n    return [\"output\", \"continue_dialogue\"];\n  }\n\n  constructor(\n    llm: BaseLanguageModelInterface,\n    longTermMemory: GenerativeAgentMemory,\n    config: GenerativeAgentConfig\n  ) {\n    super();\n    this.llm = llm;\n    this.longTermMemory = longTermMemory;\n    this.name = config.name;\n    this.age = config.age;\n    this.traits = config.traits;\n    this.status = config.status;\n    this.verbose = config.verbose ?? this.verbose;\n    this.summary = \"\";\n    this.summaryRefreshSeconds =\n      config.summaryRefreshSeconds ?? this.summaryRefreshSeconds;\n    this.lastRefreshed = new Date();\n    // this.dailySummaries = config.dailySummaries ?? this.dailySummaries;\n  }\n\n  // LLM methods\n  /**\n   * Parses a newline-separated string into a list of strings.\n   * @param text The string to parse.\n   * @returns An array of strings parsed from the input text.\n   */\n  parseList(text: string): string[] {\n    // parse a newline-seperated string into a list of strings\n    const lines: string[] = text.trim().split(\"\\n\");\n    const result: string[] = lines.map((line: string) =>\n      line.replace(/^\\s*\\d+\\.\\s*/, \"\").trim()\n    );\n    return result;\n  }\n\n  /**\n   * Creates a new LLMChain with the given prompt and the agent's language\n   * model, verbosity, output key, and memory.\n   * @param prompt The prompt to use for the LLMChain.\n   * @returns A new LLMChain instance.\n   */\n  chain(prompt: PromptTemplate): LLMChain {\n    const chain = new LLMChain({\n      llm: this.llm,\n      prompt,\n      verbose: this.verbose,\n      outputKey: \"output\", // new\n      memory: this.longTermMemory,\n    });\n    return chain;\n  }\n\n  /**\n   * Extracts the observed entity from the given observation.\n   * @param observation The observation to extract the entity from.\n   * @param runManager Optional CallbackManagerForChainRun instance.\n   * @returns The extracted entity as a string.\n   */\n  async getEntityFromObservations(\n    observation: string,\n    runManager?: CallbackManagerForChainRun\n  ): Promise<string> {\n    const prompt = PromptTemplate.fromTemplate(\n      \"What is the observed entity in the following observation? {observation}\" +\n        \"\\nEntity=\"\n    );\n\n    const result = await this.chain(prompt).call(\n      {\n        observation,\n      },\n      runManager?.getChild(\"entity_extractor\")\n    );\n\n    return result.output;\n  }\n\n  /**\n   * Extracts the action of the given entity from the given observation.\n   * @param observation The observation to extract the action from.\n   * @param entityName The name of the entity to extract the action for.\n   * @param runManager Optional CallbackManagerForChainRun instance.\n   * @returns The extracted action as a string.\n   */\n  async getEntityAction(\n    observation: string,\n    entityName: string,\n    runManager?: CallbackManagerForChainRun\n  ): Promise<string> {\n    const prompt = PromptTemplate.fromTemplate(\n      \"What is the {entity} doing in the following observation? {observation}\" +\n        \"\\nThe {entity} is\"\n    );\n\n    const result = await this.chain(prompt).call(\n      {\n        entity: entityName,\n        observation,\n      },\n      runManager?.getChild(\"entity_action_extractor\")\n    );\n    const trimmedResult = result.output.trim();\n    return trimmedResult;\n  }\n\n  /**\n   * Summarizes memories that are most relevant to an observation.\n   * @param observation The observation to summarize related memories for.\n   * @param runManager Optional CallbackManagerForChainRun instance.\n   * @returns The summarized memories as a string.\n   */\n  async summarizeRelatedMemories(\n    observation: string,\n    runManager?: CallbackManagerForChainRun\n  ): Promise<string> {\n    // summarize memories that are most relevant to an observation\n    const prompt = PromptTemplate.fromTemplate(\n      `\n{q1}?\nContext from memory:\n{relevant_memories}\nRelevant context:`\n    );\n    const entityName = await this.getEntityFromObservations(\n      observation,\n      runManager\n    );\n    const entityAction = await this.getEntityAction(\n      observation,\n      entityName,\n      runManager\n    );\n    const q1 = `What is the relationship between ${this.name} and ${entityName}`;\n    const q2 = `${entityName} is ${entityAction}`;\n    const response = await this.chain(prompt).call(\n      {\n        q1,\n        queries: [q1, q2],\n      },\n      runManager?.getChild(\"entity_relationships\")\n    );\n\n    return response.output.trim(); // added output\n  }\n\n  async _call(\n    values: ChainValues,\n    runManager?: CallbackManagerForChainRun\n  ): Promise<ChainValues> {\n    const { observation, suffix, now } = values;\n    // react to a given observation or dialogue act\n    const prompt = PromptTemplate.fromTemplate(\n      `{agent_summary_description}` +\n        `\\nIt is {current_time}.` +\n        `\\n{agent_name}'s status: {agent_status}` +\n        `\\nSummary of relevant context from {agent_name}'s memory:` +\n        \"\\n{relevant_memories}\" +\n        `\\nMost recent observations: {most_recent_memories}` +\n        `\\nObservation: {observation}` +\n        `\\n\\n${suffix}`\n    );\n\n    const agentSummaryDescription = await this.getSummary({}, runManager); // now = now in param\n    const relevantMemoriesStr = await this.summarizeRelatedMemories(\n      observation,\n      runManager\n    );\n    const currentTime = (now || new Date()).toLocaleString(\"en-US\", {\n      month: \"long\",\n      day: \"numeric\",\n      year: \"numeric\",\n      hour: \"numeric\",\n      minute: \"numeric\",\n      hour12: true,\n    });\n    const chainInputs: ChainValues = {\n      agent_summary_description: agentSummaryDescription,\n      current_time: currentTime,\n      agent_name: this.name,\n      observation,\n      agent_status: this.status,\n      most_recent_memories: \"\",\n    };\n\n    chainInputs[this.longTermMemory.getRelevantMemoriesKey()] =\n      relevantMemoriesStr;\n\n    const consumedTokens = await this.llm.getNumTokens(\n      await prompt.format({ ...chainInputs })\n    );\n\n    chainInputs[this.longTermMemory.getMostRecentMemoriesTokenKey()] =\n      consumedTokens;\n    const response = await this.chain(prompt).call(\n      chainInputs,\n      runManager?.getChild(\"reaction_from_summary\")\n    );\n\n    const rawOutput = response.output;\n    let output = rawOutput;\n    let continue_dialogue = false;\n\n    if (rawOutput.includes(\"REACT:\")) {\n      const reaction = this._cleanResponse(rawOutput.split(\"REACT:\").pop());\n      await this.addMemory(\n        `${this.name} observed ${observation} and reacted by ${reaction}`,\n        now,\n        {},\n        runManager?.getChild(\"memory\")\n      );\n      output = `${reaction}`;\n      continue_dialogue = false;\n    } else if (rawOutput.includes(\"SAY:\")) {\n      const saidValue = this._cleanResponse(rawOutput.split(\"SAY:\").pop());\n      await this.addMemory(\n        `${this.name} observed ${observation} and said ${saidValue}`,\n        now,\n        {},\n        runManager?.getChild(\"memory\")\n      );\n      output = `${this.name} said ${saidValue}`;\n      continue_dialogue = true;\n    } else if (rawOutput.includes(\"GOODBYE:\")) {\n      const farewell = this._cleanResponse(\n        rawOutput.split(\"GOODBYE:\").pop() ?? \"\"\n      );\n      await this.addMemory(\n        `${this.name} observed ${observation} and said ${farewell}`,\n        now,\n        {},\n        runManager?.getChild(\"memory\")\n      );\n      output = `${this.name} said ${farewell}`;\n      continue_dialogue = false;\n    }\n\n    return { output, continue_dialogue };\n  }\n\n  private _cleanResponse(text: string | undefined): string {\n    if (text === undefined) {\n      return \"\";\n    }\n    const regex = new RegExp(`^${this.name} `);\n    return text.replace(regex, \"\").trim();\n  }\n\n  /**\n   * Generates a reaction to the given observation.\n   * @param observation The observation to generate a reaction for.\n   * @param now Optional current date.\n   * @returns A boolean indicating whether to continue the dialogue and the output string.\n   */\n  async generateReaction(\n    observation: string,\n    now?: Date\n  ): Promise<[boolean, string]> {\n    const callToActionTemplate: string =\n      `Should {agent_name} react to the observation, and if so,` +\n      ` what would be an appropriate reaction? Respond in one line.` +\n      ` If the action is to engage in dialogue, write:\\nSAY: \"what to say\"` +\n      ` \\notherwise, write:\\nREACT: {agent_name}'s reaction (if anything).` +\n      ` \\nEither do nothing, react, or say something but not both.\\n\\n`;\n\n    const { output, continue_dialogue } = await this.call({\n      observation,\n      suffix: callToActionTemplate,\n      now,\n    });\n    return [continue_dialogue, output];\n  }\n\n  /**\n   * Generates a dialogue response to the given observation.\n   * @param observation The observation to generate a dialogue response for.\n   * @param now Optional current date.\n   * @returns A boolean indicating whether to continue the dialogue and the output string.\n   */\n  async generateDialogueResponse(\n    observation: string,\n    now?: Date\n  ): Promise<[boolean, string]> {\n    const callToActionTemplate = `What would ${this.name} say? To end the conversation, write: GOODBYE: \"what to say\". Otherwise to continue the conversation, write: SAY: \"what to say next\"\\n\\n`;\n    const { output, continue_dialogue } = await this.call({\n      observation,\n      suffix: callToActionTemplate,\n      now,\n    });\n    return [continue_dialogue, output];\n  }\n\n  // Agent stateful' summary methods\n  // Each dialog or response prompt includes a header\n  // summarizing the agent's self-description. This is\n  // updated periodically through probing it's memories\n  /**\n   * Gets the agent's summary, which includes the agent's name, age, traits,\n   * and a summary of the agent's core characteristics. The summary is\n   * updated periodically through probing the agent's memories.\n   * @param config Optional configuration object with current date and a boolean to force refresh.\n   * @param runManager Optional CallbackManagerForChainRun instance.\n   * @returns The agent's summary as a string.\n   */\n  async getSummary(\n    config?: {\n      now?: Date;\n      forceRefresh?: boolean;\n    },\n    runManager?: CallbackManagerForChainRun\n  ): Promise<string> {\n    const { now = new Date(), forceRefresh = false } = config ?? {};\n\n    const sinceRefresh = Math.floor(\n      (now.getTime() - this.lastRefreshed.getTime()) / 1000\n    );\n\n    if (\n      !this.summary ||\n      sinceRefresh >= this.summaryRefreshSeconds ||\n      forceRefresh\n    ) {\n      this.summary = await this.computeAgentSummary(runManager);\n      this.lastRefreshed = now;\n    }\n\n    let age;\n    if (this.age) {\n      age = this.age;\n    } else {\n      age = \"N/A\";\n    }\n\n    return `Name: ${this.name} (age: ${age})\nInnate traits: ${this.traits}\n${this.summary}`;\n  }\n\n  /**\n   * Computes the agent's summary by summarizing the agent's core\n   * characteristics given the agent's relevant memories.\n   * @param runManager Optional CallbackManagerForChainRun instance.\n   * @returns The computed summary as a string.\n   */\n  async computeAgentSummary(\n    runManager?: CallbackManagerForChainRun\n  ): Promise<string> {\n    const prompt = PromptTemplate.fromTemplate(\n      \"How would you summarize {name}'s core characteristics given the following statements:\\n\" +\n        \"----------\" +\n        \"{relevant_memories}\" +\n        \"----------\" +\n        \"Do not embellish.\" +\n        \"\\n\\nSummary: \"\n    );\n    // the agent seeks to think about their core characterisitics\n    const result = await this.chain(prompt).call(\n      {\n        name: this.name,\n        queries: [`${this.name}'s core characteristics`],\n      },\n      runManager?.getChild(\"compute_agent_summary\")\n    );\n    return result.output.trim();\n  }\n\n  /**\n   * Returns a full header of the agent's status, summary, and current time.\n   * @param config Optional configuration object with current date and a boolean to force refresh.\n   * @returns The full header as a string.\n   */\n  getFullHeader(\n    config: {\n      now?: Date;\n      forceRefresh?: boolean;\n    } = {}\n  ): string {\n    const { now = new Date(), forceRefresh = false } = config;\n    // return a full header of the agent's status, summary, and current time.\n    const summary = this.getSummary({ now, forceRefresh });\n    const currentTimeString = now.toLocaleString(\"en-US\", {\n      month: \"long\",\n      day: \"numeric\",\n      year: \"numeric\",\n      hour: \"numeric\",\n      minute: \"numeric\",\n      hour12: true,\n    });\n    return `${summary}\\nIt is ${currentTimeString}.\\n${this.name}'s status: ${this.status}`;\n  }\n\n  /**\n   * Adds a memory to the agent's long-term memory.\n   * @param memoryContent The content of the memory to add.\n   * @param now Optional current date.\n   * @param metadata Optional metadata for the memory.\n   * @param callbacks Optional Callbacks instance.\n   * @returns The result of adding the memory to the agent's long-term memory.\n   */\n  async addMemory(\n    memoryContent: string,\n    now?: Date,\n    metadata?: Record<string, unknown>,\n    callbacks?: Callbacks\n  ) {\n    return this.longTermMemory.addMemory(\n      memoryContent,\n      now,\n      metadata,\n      callbacks\n    );\n  }\n}\n"],"mappings":"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"}