{"version":3,"file":"chrome_ai.cjs","names":["LLM","IterableReadableStream","GenerationChunk"],"sources":["../../../src/experimental/llms/chrome_ai.ts"],"sourcesContent":["import type { BaseLanguageModelCallOptions } from \"@langchain/core/language_models/base\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { GenerationChunk } from \"@langchain/core/outputs\";\nimport { IterableReadableStream } from \"@langchain/core/utils/stream\";\nimport { BaseLLMParams, LLM } from \"@langchain/core/language_models/llms\";\n\nexport interface AILanguageModelFactory {\n  create(options?: AILanguageModelCreateOptions): Promise<AILanguageModel>;\n  capabilities(): Promise<AILanguageModelCapabilities>;\n}\n\nexport interface AILanguageModel extends EventTarget {\n  prompt(\n    input: AILanguageModelPromptInput,\n    options?: AILanguageModelPromptOptions\n  ): Promise<string>;\n  promptStreaming(\n    input: AILanguageModelPromptInput,\n    options?: AILanguageModelPromptOptions\n  ): ReadableStream;\n\n  countPromptTokens(\n    input: AILanguageModelPromptInput,\n    options?: AILanguageModelPromptOptions\n  ): Promise<number>;\n\n  get maxTokens(): number;\n  get tokensSoFar(): number;\n  get tokensLeft(): number;\n\n  get topK(): number;\n  get temperature(): number;\n\n  oncontextoverflow: (event: Event) => void;\n\n  clone(options?: AILanguageModelCloneOptions): Promise<AILanguageModel>;\n  destroy(): void;\n}\n\ninterface AILanguageModelCapabilities {\n  readonly available: AICapabilityAvailability;\n  languageAvailable(languageTag: string): AICapabilityAvailability;\n\n  get defaultTopK(): number | undefined;\n  get maxTopK(): number | undefined;\n  get defaultTemperature(): number | undefined;\n  get maxTemperature(): number | undefined;\n}\n\ninterface AILanguageModelCreateOptions {\n  signal?: AbortSignal;\n  monitor?: AICreateMonitorCallback;\n  systemPrompt?: string;\n  initialPrompts?: AILanguageModelInitialPrompt[];\n  topK: number;\n  temperature: number;\n}\n\nexport interface AILanguageModelInitialPrompt {\n  role: AILanguageModelInitialPromptRole;\n  content: string;\n}\n\nexport interface AILanguageModelPrompt {\n  role: AILanguageModelPromptRole;\n  content: string;\n}\n\nexport interface AILanguageModelPromptOptions {\n  signal?: AbortSignal;\n}\n\nexport interface AILanguageModelCloneOptions {\n  signal?: AbortSignal;\n}\n\nexport type AILanguageModelPromptInput =\n  | string\n  | AILanguageModelPrompt\n  | AILanguageModelPrompt[];\n\nenum AILanguageModelInitialPromptRole {\n  \"system\",\n  \"user\",\n  \"assistant\",\n}\n\nenum AILanguageModelPromptRole {\n  \"user\",\n  \"assistant\",\n}\n\nexport type AICapabilityAvailability = \"yes\" | \"no\";\nexport type AICreateMonitorCallback = () => void;\n\nexport interface ChromeAIInputs extends BaseLLMParams {\n  topK?: number;\n  temperature?: number;\n  systemPrompt?: string;\n}\n\nexport interface ChromeAICallOptions extends BaseLanguageModelCallOptions {}\n\n/**\n * To use this model you need to have the `Built-in AI Early Preview Program`\n * for Chrome. You can find more information about the program here:\n * @link https://developer.chrome.com/docs/ai/built-in\n *\n * @example\n * ```typescript\n * // Initialize the ChromeAI model.\n * const model = new ChromeAI({\n *   temperature: 0.5, // Optional. Default is 0.5.\n *   topK: 40, // Optional. Default is 40.\n * });\n *\n * // Call the model with a message and await the response.\n * const response = await model.invoke([\n *   new HumanMessage({ content: \"My name is John.\" }),\n * ]);\n * ```\n */\nexport class ChromeAI extends LLM<ChromeAICallOptions> {\n  temperature?: number;\n\n  topK?: number;\n\n  systemPrompt?: string;\n\n  static lc_name() {\n    return \"ChromeAI\";\n  }\n\n  constructor(inputs?: ChromeAIInputs) {\n    super({\n      ...inputs,\n    });\n    this.temperature = inputs?.temperature ?? this.temperature;\n    this.topK = inputs?.topK ?? this.topK;\n    this.systemPrompt = inputs?.systemPrompt;\n  }\n\n  _llmType() {\n    return \"chrome_ai\";\n  }\n\n  /**\n   * Initialize the model. This method may be called before invoking the model\n   * to set up a chat session in advance.\n   */\n  protected async createSession() {\n    // oxlint-disable-next-line typescript/no-explicit-any\n    let aiInstance: any;\n    try {\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore Experimental browser-only global\n      aiInstance = LanguageModel;\n      // oxlint-disable-next-line typescript/no-explicit-any\n    } catch (e: any) {\n      throw new Error(\n        `Could not initialize ChromeAI instance. Make sure you are running a version of Chrome with the proper experimental flags enabled.\\n\\nError message: ${e.message}`\n      );\n    }\n    const availability = await aiInstance.availability();\n    if (availability === \"no\") {\n      throw new Error(\"The AI model is not available.\");\n    } else if (availability === \"after-download\") {\n      throw new Error(\"The AI model is not yet downloaded.\");\n    }\n\n    const session = await aiInstance.create({\n      systemPrompt: this.systemPrompt,\n      topK: this.topK,\n      temperature: this.temperature,\n    });\n\n    return session;\n  }\n\n  async *_streamResponseChunks(\n    prompt: string,\n    _options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<GenerationChunk> {\n    let session;\n    try {\n      session = await this.createSession();\n\n      const stream = session.promptStreaming(prompt);\n      const iterableStream =\n        // oxlint-disable-next-line typescript/no-explicit-any\n        IterableReadableStream.fromReadableStream<any>(stream);\n\n      for await (const chunk of iterableStream) {\n        const newContent = chunk;\n        yield new GenerationChunk({\n          text: newContent,\n        });\n        await runManager?.handleLLMNewToken(newContent);\n      }\n    } finally {\n      session?.destroy();\n    }\n  }\n\n  async _call(\n    prompt: string,\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<string> {\n    const chunks = [];\n    for await (const chunk of this._streamResponseChunks(\n      prompt,\n      options,\n      runManager\n    )) {\n      chunks.push(chunk.text);\n    }\n    return chunks.join(\"\");\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0HA,IAAa,WAAb,cAA8BA,qCAAAA,IAAyB;CACrD;CAEA;CAEA;CAEA,OAAO,UAAU;AACf,SAAO;;CAGT,YAAY,QAAyB;AACnC,QAAM,EACJ,GAAG,QACJ,CAAC;AACF,OAAK,cAAc,QAAQ,eAAe,KAAK;AAC/C,OAAK,OAAO,QAAQ,QAAQ,KAAK;AACjC,OAAK,eAAe,QAAQ;;CAG9B,WAAW;AACT,SAAO;;;;;;CAOT,MAAgB,gBAAgB;EAE9B,IAAI;AACJ,MAAI;AAGF,gBAAa;WAEN,GAAQ;AACf,SAAM,IAAI,MACR,uJAAuJ,EAAE,UAC1J;;EAEH,MAAM,eAAe,MAAM,WAAW,cAAc;AACpD,MAAI,iBAAiB,KACnB,OAAM,IAAI,MAAM,iCAAiC;WACxC,iBAAiB,iBAC1B,OAAM,IAAI,MAAM,sCAAsC;AASxD,SANgB,MAAM,WAAW,OAAO;GACtC,cAAc,KAAK;GACnB,MAAM,KAAK;GACX,aAAa,KAAK;GACnB,CAAC;;CAKJ,OAAO,sBACL,QACA,UACA,YACiC;EACjC,IAAI;AACJ,MAAI;AACF,aAAU,MAAM,KAAK,eAAe;GAEpC,MAAM,SAAS,QAAQ,gBAAgB,OAAO;GAC9C,MAAM,iBAEJC,6BAAAA,uBAAuB,mBAAwB,OAAO;AAExD,cAAW,MAAM,SAAS,gBAAgB;IACxC,MAAM,aAAa;AACnB,UAAM,IAAIC,wBAAAA,gBAAgB,EACxB,MAAM,YACP,CAAC;AACF,UAAM,YAAY,kBAAkB,WAAW;;YAEzC;AACR,YAAS,SAAS;;;CAItB,MAAM,MACJ,QACA,SACA,YACiB;EACjB,MAAM,SAAS,EAAE;AACjB,aAAW,MAAM,SAAS,KAAK,sBAC7B,QACA,SACA,WACD,CACC,QAAO,KAAK,MAAM,KAAK;AAEzB,SAAO,OAAO,KAAK,GAAG"}