code: import json
  from typing import Any, Dict, Sequence, Tuple
  
  import httpx
  from httpx import Timeout
  
  from llama_index.legacy.bridge.pydantic import Field
  from llama_index.legacy.constants import DEFAULT_CONTEXT_WINDOW, DEFAULT_NUM_OUTPUTS
  from llama_index.legacy.core.llms.types import (
      ChatMessage,
      ChatResponse,
      ChatResponseGen,
      CompletionResponse,
      CompletionResponseGen,
      LLMMetadata,
      MessageRole,
  )
  from llama_index.legacy.llms.base import llm_chat_callback, llm_completion_callback
  from llama_index.legacy.llms.custom import CustomLLM
  
  DEFAULT_REQUEST_TIMEOUT = 30.0
  
  
  def get_addtional_kwargs(
      response: Dict[str, Any], exclude: Tuple[str, ...]
  ) -> Dict[str, Any]:
      return {k: v for k, v in response.items() if k not in exclude}
  
  
  class Ollama(CustomLLM):
      base_url: str = Field(
          default="http://localhost:11434",
          description="Base url the model is hosted under.",
      )
      model: str = Field(description="The Ollama model to use.")
      temperature: float = Field(
          default=0.75,
          description="The temperature to use for sampling.",
          gte=0.0,
          lte=1.0,
      )
      context_window: int = Field(
          default=DEFAULT_CONTEXT_WINDOW,
          description="The maximum number of context tokens for the model.",
          gt=0,
      )
      request_timeout: float = Field(
          default=DEFAULT_REQUEST_TIMEOUT,
          description="The timeout for making http request to Ollama API server",
      )
      prompt_key: str = Field(
          default="prompt", description="The key to use for the prompt in API calls."
      )
      additional_kwargs: Dict[str, Any] = Field(
          default_factory=dict,
          description="Additional model parameters for the Ollama API.",
      )
  
      @classmethod
      def class_name(cls) -> str:
          return "Ollama_llm"
  
      @property
      def metadata(self) -> LLMMetadata:
          """LLM metadata."""
          return LLMMetadata(
              context_window=self.context_window,
              num_output=DEFAULT_NUM_OUTPUTS,
              model_name=self.model,
              is_chat_model=True,  # Ollama supports chat API for all models
          )
  
      @property
      def _model_kwargs(self) -> Dict[str, Any]:
          base_kwargs = {
              "temperature": self.temperature,
              "num_ctx": self.context_window,
          }
          return {
              **base_kwargs,
              **self.additional_kwargs,
          }
  
      @llm_chat_callback()
      def chat(self, messages: Sequence[ChatMessage], **kwargs: Any) -> ChatResponse:
          payload = {
              "model": self.model,
              "messages": [
                  {
                      "role": message.role.value,
                      "content": message.content,
                      **message.additional_kwargs,
                  }
                  for message in messages
              ],
              "options": self._model_kwargs,
              "stream": False,
              **kwargs,
          }
  
          with httpx.Client(timeout=Timeout(self.request_timeout)) as client:
              response = client.post(
                  url=f"{self.base_url}/api/chat",
                  json=payload,
              )
              response.raise_for_status()
              raw = response.json()
              message = raw["message"]
              return ChatResponse(
                  message=ChatMessage(
                      content=message.get("content"),
                      role=MessageRole(message.get("role")),
                      additional_kwargs=get_addtional_kwargs(
                          message, ("content", "role")
                      ),
                  ),
                  raw=raw,
                  additional_kwargs=get_addtional_kwargs(raw, ("message",)),
              )
  
      @llm_chat_callback()
      def stream_chat(
          self, messages: Sequence[ChatMessage], **kwargs: Any
      ) -> ChatResponseGen:
          payload = {
              "model": self.model,
              "messages": [
                  {
                      "role": message.role.value,
                      "content": message.content,
                      **message.additional_kwargs,
                  }
                  for message in messages
              ],
              "options": self._model_kwargs,
              "stream": True,
              **kwargs,
          }
  
          with httpx.Client(timeout=Timeout(self.request_timeout)) as client:
              with client.stream(
                  method="POST",
                  url=f"{self.base_url}/api/chat",
                  json=payload,
              ) as response:
                  response.raise_for_status()
                  text = ""
                  for line in response.iter_lines():
                      if line:
                          chunk = json.loads(line)
                          if "done" in chunk and chunk["done"]:
                              break
                          message = chunk["message"]
                          delta = message.get("content")
                          text += delta
                          yield ChatResponse(
                              message=ChatMessage(
                                  content=text,
                                  role=MessageRole(message.get("role")),
                                  additional_kwargs=get_addtional_kwargs(
                                      message, ("content", "role")
                                  ),
                              ),
                              delta=delta,
                              raw=chunk,
                              additional_kwargs=get_addtional_kwargs(chunk, ("message",)),
                          )
  
      @llm_completion_callback()
      def complete(
          self, prompt: str, formatted: bool = False, **kwargs: Any
      ) -> CompletionResponse:
          payload = {
              self.prompt_key: prompt,
              "model": self.model,
              "options": self._model_kwargs,
              "stream": False,
              **kwargs,
          }
  
          with httpx.Client(timeout=Timeout(self.request_timeout)) as client:
              response = client.post(
                  url=f"{self.base_url}/api/generate",
                  json=payload,
              )
              response.raise_for_status()
              raw = response.json()
              text = raw.get("response")
              return CompletionResponse(
                  text=text,
                  raw=raw,
                  additional_kwargs=get_addtional_kwargs(raw, ("response",)),
              )
  
      @llm_completion_callback()
      def stream_complete(
          self, prompt: str, formatted: bool = False, **kwargs: Any
      ) -> CompletionResponseGen:
          payload = {
              self.prompt_key: prompt,
              "model": self.model,
              "options": self._model_kwargs,
              "stream": True,
              **kwargs,
          }
  
          with httpx.Client(timeout=Timeout(self.request_timeout)) as client:
              with client.stream(
                  method="POST",
                  url=f"{self.base_url}/api/generate",
                  json=payload,
              ) as response:
                  response.raise_for_status()
                  text = ""
                  for line in response.iter_lines():
                      if line:
                          chunk = json.loads(line)
                          delta = chunk.get("response")
                          text += delta
                          yield CompletionResponse(
                              delta=delta,
                              text=text,
                              raw=chunk,
                              additional_kwargs=get_addtional_kwargs(
                                  chunk, ("response",)
                              ),
                          )
  
apis: llama_index.legacy.llms.base.llm_completion_callback llama_index.legacy.core.llms.types.LLMMetadata llama_index.legacy.llms.base.llm_chat_callback llama_index.legacy.bridge.pydantic.Field
extract_api: [((816, 911), 'llama_index.legacy.bridge.pydantic.Field', 'Field', ([], {'default': '"""http://localhost:11434"""', 'description': '"""Base url the model is hosted under."""'}), "(default='http://localhost:11434', description=\n    'Base url the model is hosted under.')\n", (821, 911), False, 'from llama_index.legacy.bridge.pydantic import Field\n'), ((947, 992), 'llama_index.legacy.bridge.pydantic.Field', 'Field', ([], {'description': '"""The Ollama model to use."""'}), "(description='The Ollama model to use.')\n", (952, 992), False, 'from llama_index.legacy.bridge.pydantic import Field\n'), ((1018, 1112), 'llama_index.legacy.bridge.pydantic.Field', 'Field', ([], {'default': '(0.75)', 'description': '"""The temperature to use for sampling."""', 'gte': '(0.0)', 'lte': '(1.0)'}), "(default=0.75, description='The temperature to use for sampling.', gte\n    =0.0, lte=1.0)\n", (1023, 1112), False, 'from llama_index.legacy.bridge.pydantic import Field\n'), ((1173, 1288), 'llama_index.legacy.bridge.pydantic.Field', 'Field', ([], {'default': 'DEFAULT_CONTEXT_WINDOW', 'description': '"""The maximum number of context tokens for the model."""', 'gt': '(0)'}), "(default=DEFAULT_CONTEXT_WINDOW, description=\n    'The maximum number of context tokens for the model.', gt=0)\n", (1178, 1288), False, 'from llama_index.legacy.bridge.pydantic import Field\n'), ((1344, 1459), 'llama_index.legacy.bridge.pydantic.Field', 'Field', ([], {'default': 'DEFAULT_REQUEST_TIMEOUT', 'description': '"""The timeout for making http request to Ollama API server"""'}), "(default=DEFAULT_REQUEST_TIMEOUT, description=\n    'The timeout for making http request to Ollama API server')\n", (1349, 1459), False, 'from llama_index.legacy.bridge.pydantic import Field\n'), ((1500, 1587), 'llama_index.legacy.bridge.pydantic.Field', 'Field', ([], {'default': '"""prompt"""', 'description': '"""The key to use for the prompt in API calls."""'}), "(default='prompt', description=\n    'The key to use for the prompt in API calls.')\n", (1505, 1587), False, 'from llama_index.legacy.bridge.pydantic import Field\n'), ((1637, 1732), 'llama_index.legacy.bridge.pydantic.Field', 'Field', ([], {'default_factory': 'dict', 'description': '"""Additional model parameters for the Ollama API."""'}), "(default_factory=dict, description=\n    'Additional model parameters for the Ollama API.')\n", (1642, 1732), False, 'from llama_index.legacy.bridge.pydantic import Field\n'), ((2434, 2453), 'llama_index.legacy.llms.base.llm_chat_callback', 'llm_chat_callback', ([], {}), '()\n', (2451, 2453), False, 'from llama_index.legacy.llms.base import llm_chat_callback, llm_completion_callback\n'), ((3730, 3749), 'llama_index.legacy.llms.base.llm_chat_callback', 'llm_chat_callback', ([], {}), '()\n', (3747, 3749), False, 'from llama_index.legacy.llms.base import llm_chat_callback, llm_completion_callback\n'), ((5575, 5600), 'llama_index.legacy.llms.base.llm_completion_callback', 'llm_completion_callback', ([], {}), '()\n', (5598, 5600), False, 'from llama_index.legacy.llms.base import llm_chat_callback, llm_completion_callback\n'), ((6418, 6443), 'llama_index.legacy.llms.base.llm_completion_callback', 'llm_completion_callback', ([], {}), '()\n', (6441, 6443), False, 'from llama_index.legacy.llms.base import llm_chat_callback, llm_completion_callback\n'), ((1926, 2053), 'llama_index.legacy.core.llms.types.LLMMetadata', 'LLMMetadata', ([], {'context_window': 'self.context_window', 'num_output': 'DEFAULT_NUM_OUTPUTS', 'model_name': 'self.model', 'is_chat_model': '(True)'}), '(context_window=self.context_window, num_output=\n    DEFAULT_NUM_OUTPUTS, model_name=self.model, is_chat_model=True)\n', (1937, 2053), False, 'from llama_index.legacy.core.llms.types import ChatMessage, ChatResponse, ChatResponseGen, CompletionResponse, CompletionResponseGen, LLMMetadata, MessageRole\n'), ((2992, 3021), 'httpx.Timeout', 'Timeout', (['self.request_timeout'], {}), '(self.request_timeout)\n', (2999, 3021), False, 'from httpx import Timeout\n'), ((4311, 4340), 'httpx.Timeout', 'Timeout', (['self.request_timeout'], {}), '(self.request_timeout)\n', (4318, 4340), False, 'from httpx import Timeout\n'), ((5943, 5972), 'httpx.Timeout', 'Timeout', (['self.request_timeout'], {}), '(self.request_timeout)\n', (5950, 5972), False, 'from httpx import Timeout\n'), ((6795, 6824), 'httpx.Timeout', 'Timeout', (['self.request_timeout'], {}), '(self.request_timeout)\n', (6802, 6824), False, 'from httpx import Timeout\n'), ((4704, 4720), 'json.loads', 'json.loads', (['line'], {}), '(line)\n', (4714, 4720), False, 'import json\n'), ((7192, 7208), 'json.loads', 'json.loads', (['line'], {}), '(line)\n', (7202, 7208), False, 'import json\n')]