code: from llama_index.core import Document
  from llama_index.core.node_parser import CodeSplitter
  from llama_index.retrievers.bm25 import BM25Retriever
  from llama_index.core import VectorStoreIndex
  from llama_index.core.query_engine import RetrieverQueryEngine
  from llama_index.core import get_response_synthesizer
  from llama_index.core import PromptTemplate
  from .defaults import DefaultLLM, DefaultEmbedder
  from .default_prompt import DEFAULT_PROMPT
  
  MAX_CHARS = 1500
  K = 3
  
  class ActionEngine:
      def __init__(self, llm=None, embedding=None):
          if (llm is None):
              llm = DefaultLLM()
          if (embedding is None):
              embedding = DefaultEmbedder()
  
          self.llm = llm
          self.embedding = embedding
  
      def _get_index(self, html):
          text_list = [html]
          documents = [Document(text=t) for t in text_list]
  
          splitter = CodeSplitter(
              language="html",
              chunk_lines=40,  # lines per chunk
              chunk_lines_overlap=200,  # lines overlap between chunks
              max_chars=MAX_CHARS,  # max chars per chunk
          )
          nodes = splitter.get_nodes_from_documents(documents)
          nodes = [node for node in nodes if node.text]
  
          index = VectorStoreIndex(nodes, embed_model=self.embedding)
  
          return index
  
      def get_query_engine(self, state):
          html = state
          index = self._get_index(html)
  
          retriever = BM25Retriever.from_defaults(
              index=index,
              similarity_top_k=K,
          )
  
          response_synthesizer = get_response_synthesizer(streaming=True, llm=self.llm)
  
          # assemble query engine
          query_engine = RetrieverQueryEngine(
              retriever=retriever,
              response_synthesizer=response_synthesizer,
          )
  
          prompt_template = PromptTemplate(DEFAULT_PROMPT)
  
          query_engine.update_prompts(
              {"response_synthesizer:text_qa_template": prompt_template}
          )
  
          return query_engine
  
apis: llama_index.core.node_parser.CodeSplitter llama_index.retrievers.bm25.BM25Retriever.from_defaults llama_index.core.PromptTemplate llama_index.core.VectorStoreIndex llama_index.core.query_engine.RetrieverQueryEngine llama_index.core.get_response_synthesizer llama_index.core.Document
extract_api: [((869, 964), 'llama_index.core.node_parser.CodeSplitter', 'CodeSplitter', ([], {'language': '"""html"""', 'chunk_lines': '(40)', 'chunk_lines_overlap': '(200)', 'max_chars': 'MAX_CHARS'}), "(language='html', chunk_lines=40, chunk_lines_overlap=200,\n    max_chars=MAX_CHARS)\n", (881, 964), False, 'from llama_index.core.node_parser import CodeSplitter\n'), ((1226, 1277), 'llama_index.core.VectorStoreIndex', 'VectorStoreIndex', (['nodes'], {'embed_model': 'self.embedding'}), '(nodes, embed_model=self.embedding)\n', (1242, 1277), False, 'from llama_index.core import VectorStoreIndex\n'), ((1420, 1480), 'llama_index.retrievers.bm25.BM25Retriever.from_defaults', 'BM25Retriever.from_defaults', ([], {'index': 'index', 'similarity_top_k': 'K'}), '(index=index, similarity_top_k=K)\n', (1447, 1480), False, 'from llama_index.retrievers.bm25 import BM25Retriever\n'), ((1548, 1602), 'llama_index.core.get_response_synthesizer', 'get_response_synthesizer', ([], {'streaming': '(True)', 'llm': 'self.llm'}), '(streaming=True, llm=self.llm)\n', (1572, 1602), False, 'from llama_index.core import get_response_synthesizer\n'), ((1659, 1748), 'llama_index.core.query_engine.RetrieverQueryEngine', 'RetrieverQueryEngine', ([], {'retriever': 'retriever', 'response_synthesizer': 'response_synthesizer'}), '(retriever=retriever, response_synthesizer=\n    response_synthesizer)\n', (1679, 1748), False, 'from llama_index.core.query_engine import RetrieverQueryEngine\n'), ((1806, 1836), 'llama_index.core.PromptTemplate', 'PromptTemplate', (['DEFAULT_PROMPT'], {}), '(DEFAULT_PROMPT)\n', (1820, 1836), False, 'from llama_index.core import PromptTemplate\n'), ((812, 828), 'llama_index.core.Document', 'Document', ([], {'text': 't'}), '(text=t)\n', (820, 828), False, 'from llama_index.core import Document\n')]