code: """RAG LLM."""
  
  from typing import Any
  
  from llama_index.core.constants import DEFAULT_CONTEXT_WINDOW
  from llama_index.core.llms import (
      CompletionResponse,
      CompletionResponseGen,
      CustomLLM,
      LLMMetadata,
  )
  from llama_index.core.llms.callbacks import llm_completion_callback
  from pydantic import Field
  
  from metagpt.config2 import config
  from metagpt.llm import LLM
  from metagpt.provider.base_llm import BaseLLM
  from metagpt.utils.async_helper import run_coroutine_in_new_loop
  from metagpt.utils.token_counter import TOKEN_MAX
  
  
  class RAGLLM(CustomLLM):
      """LlamaIndex's LLM is different from MetaGPT's LLM.
  
      Inherit CustomLLM from llamaindex, making MetaGPT's LLM can be used by LlamaIndex.
      """
  
      model_infer: BaseLLM = Field(..., description="The MetaGPT's LLM.")
      context_window: int = TOKEN_MAX.get(config.llm.model, DEFAULT_CONTEXT_WINDOW)
      num_output: int = config.llm.max_token
      model_name: str = config.llm.model
  
      @property
      def metadata(self) -> LLMMetadata:
          """Get LLM metadata."""
          return LLMMetadata(context_window=self.context_window, num_output=self.num_output, model_name=self.model_name)
  
      @llm_completion_callback()
      def complete(self, prompt: str, **kwargs: Any) -> CompletionResponse:
          return run_coroutine_in_new_loop(self.acomplete(prompt, **kwargs))
  
      @llm_completion_callback()
      async def acomplete(self, prompt: str, formatted: bool = False, **kwargs: Any) -> CompletionResponse:
          text = await self.model_infer.aask(msg=prompt, stream=False)
          return CompletionResponse(text=text)
  
      @llm_completion_callback()
      def stream_complete(self, prompt: str, **kwargs: Any) -> CompletionResponseGen:
          ...
  
  
  def get_rag_llm(model_infer: BaseLLM = None) -> RAGLLM:
      """Get llm that can be used by LlamaIndex."""
      return RAGLLM(model_infer=model_infer or LLM())
  
apis: llama_index.core.llms.LLMMetadata llama_index.core.llms.callbacks.llm_completion_callback llama_index.core.llms.CompletionResponse
extract_api: [((751, 795), 'pydantic.Field', 'Field', (['...'], {'description': '"""The MetaGPT\'s LLM."""'}), '(..., description="The MetaGPT\'s LLM.")\n', (756, 795), False, 'from pydantic import Field\n'), ((822, 877), 'metagpt.utils.token_counter.TOKEN_MAX.get', 'TOKEN_MAX.get', (['config.llm.model', 'DEFAULT_CONTEXT_WINDOW'], {}), '(config.llm.model, DEFAULT_CONTEXT_WINDOW)\n', (835, 877), False, 'from metagpt.utils.token_counter import TOKEN_MAX\n'), ((1171, 1196), 'llama_index.core.llms.callbacks.llm_completion_callback', 'llm_completion_callback', ([], {}), '()\n', (1194, 1196), False, 'from llama_index.core.llms.callbacks import llm_completion_callback\n'), ((1352, 1377), 'llama_index.core.llms.callbacks.llm_completion_callback', 'llm_completion_callback', ([], {}), '()\n', (1375, 1377), False, 'from llama_index.core.llms.callbacks import llm_completion_callback\n'), ((1604, 1629), 'llama_index.core.llms.callbacks.llm_completion_callback', 'llm_completion_callback', ([], {}), '()\n', (1627, 1629), False, 'from llama_index.core.llms.callbacks import llm_completion_callback\n'), ((1061, 1168), 'llama_index.core.llms.LLMMetadata', 'LLMMetadata', ([], {'context_window': 'self.context_window', 'num_output': 'self.num_output', 'model_name': 'self.model_name'}), '(context_window=self.context_window, num_output=self.num_output,\n    model_name=self.model_name)\n', (1072, 1168), False, 'from llama_index.core.llms import CompletionResponse, CompletionResponseGen, CustomLLM, LLMMetadata\n'), ((1568, 1597), 'llama_index.core.llms.CompletionResponse', 'CompletionResponse', ([], {'text': 'text'}), '(text=text)\n', (1586, 1597), False, 'from llama_index.core.llms import CompletionResponse, CompletionResponseGen, CustomLLM, LLMMetadata\n'), ((1879, 1884), 'metagpt.llm.LLM', 'LLM', ([], {}), '()\n', (1882, 1884), False, 'from metagpt.llm import LLM\n')]