Skip to content
Snippets Groups Projects
Unverified Commit 6ba3f55c authored by Sean Smith's avatar Sean Smith Committed by GitHub
Browse files

Contextual Generate model (#17913)

parent 5e37074b
No related branches found
No related tags found
No related merge requests found
Showing
with 413 additions and 0 deletions
poetry_requirements(
name="poetry",
)
# Contextual LLM Integration for LlamaIndex
This package provides a Contextual LLM integration for LlamaIndex.
## Installation
```bash
pip install llama-index-llms-contextual
```
## Usage
```python
from llama_index.llms.contextual import Contextual
llm = Contextual(model="contextual-clm", api_key="your_api_key")
response = llm.complete("Explain the importance of Grounded Language Models.")
```
python_sources()
from llama_index.llms.contextual.base import Contextual
__all__ = ["Contextual"]
from typing import Any, Optional
from llama_index.llms.openai_like import OpenAILike
from pydantic import Field
from typing import List
from llama_index.core.llms.callbacks import (
llm_chat_callback,
llm_completion_callback,
)
from llama_index.core.base.llms.types import (
CompletionResponse,
ChatResponse,
ChatResponseGen,
MessageRole,
ChatMessage,
)
from contextual import ContextualAI
class Contextual(OpenAILike):
"""
Generate a response using Contextual's Grounded Language Model (GLM), an LLM engineered specifically to prioritize faithfulness to in-context retrievals over parametric knowledge to reduce hallucinations in Retrieval-Augmented Generation.
The total request cannot exceed 32,000 tokens. Email glm-feedback@contextual.ai with any feedback or questions.
Examples:
`pip install llama-index-llms-contextual`
```python
from llama_index.llms.contextual import Contextual
# Set up the Contextual class with the required model and API key
llm = Contextual(model="contextual-clm", api_key="your_api_key")
# Call the complete method with a query
response = llm.complete("Explain the importance of low latency LLMs")
print(response)
```
"""
model: str = Field(
description="The model to use. Currently only supports `v1`.", default="v1"
)
api_key: str = Field(description="The API key to use.", default=None)
base_url: str = Field(
description="The base URL to use.",
default="https://api.contextual.ai/v1/generate",
)
avoid_commentary: bool = Field(
description="Flag to indicate whether the model should avoid providing additional commentary in responses. Commentary is conversational in nature and does not contain verifiable claims; therefore, commentary is not strictly grounded in available context. However, commentary may provide useful context which improves the helpfulness of responses.",
default=False,
)
client: Any = Field(default=None, description="Contextual AI Client")
def __init__(
self,
model: str,
api_key: str,
base_url: str = None,
avoid_commentary: bool = False,
**openai_llm_kwargs: Any,
) -> None:
super().__init__(
model=model,
api_key=api_key,
api_base=base_url,
is_chat_model=openai_llm_kwargs.pop("is_chat_model", True),
**openai_llm_kwargs,
)
try:
self.client = ContextualAI(api_key=api_key, base_url=base_url)
except Exception as e:
raise ValueError(f"Error initializing ContextualAI client: {e}")
@classmethod
def class_name(cls) -> str:
"""Get class name."""
return "contextual-clm"
# Synchronous Methods
@llm_completion_callback()
def complete(
self, prompt: str, knowledge: Optional[List[str]] = None, **kwargs
) -> CompletionResponse:
"""
Generate completion for the given prompt.
Args:
prompt (str): The input prompt to generate completion for.
**kwargs: Additional keyword arguments for the API request.
Returns:
str: The generated text completion.
"""
messages_list = [{"role": MessageRole.USER, "content": prompt}]
response = self._generate(
knowledge=knowledge,
messages=messages_list,
model=self.model,
system_prompt=self.system_prompt,
**kwargs,
)
return CompletionResponse(text=response)
@llm_chat_callback()
def chat(self, messages: List[ChatMessage], **kwargs) -> ChatResponse:
"""
Generate a chat response for the given messages.
"""
messages_list = [
{"role": msg.role, "content": msg.blocks[0].text} for msg in messages
]
response = self._generate(
knowledge=kwargs.get("knowledge_base", None),
messages=messages_list,
model=self.model,
system_prompt=self.system_prompt,
**kwargs,
)
return ChatResponse(
message=ChatMessage(role=MessageRole.ASSISTANT, content=response)
)
@llm_chat_callback()
def stream_chat(self, messages: List[ChatMessage], **kwargs) -> ChatResponseGen:
"""
Generate a chat response for the given messages.
"""
raise NotImplementedError("stream methods not implemented in Contextual")
@llm_completion_callback()
def stream_complete(self, prompt: str, **kwargs) -> ChatResponseGen:
"""
Generate a chat response for the given messages.
"""
raise NotImplementedError("stream methods not implemented in Contextual")
# ===== Async Endpoints =====
@llm_chat_callback()
async def achat(
self,
messages: Sequence[ChatMessage],
**kwargs: Any,
) -> ChatResponse:
raise NotImplementedError("async methods not implemented in Contextual")
@llm_chat_callback()
async def astream_chat(
self,
messages: Sequence[ChatMessage],
**kwargs: Any,
) -> ChatResponseAsyncGen:
raise NotImplementedError("async methods not implemented in Contextual")
@llm_completion_callback()
async def acomplete(
self, prompt: str, formatted: bool = False, **kwargs: Any
) -> CompletionResponse:
raise NotImplementedError("async methods not implemented in Contextual")
@llm_completion_callback()
async def astream_complete(
self, prompt: str, formatted: bool = False, **kwargs: Any
) -> CompletionResponseAsyncGen:
raise NotImplementedError("async methods not implemented in Contextual")
def _generate(
self, knowledge, messages, system_prompt, **kwargs
) -> CompletionResponse:
"""
Generate completion for the given prompt.
"""
raw_message = self.client.generate.create(
messages=messages,
knowledge=knowledge or [],
model=self.model,
system_prompt=system_prompt,
avoid_commentary=self.avoid_commentary,
temperature=kwargs.get("temperature", 0.0),
max_new_tokens=kwargs.get("max_tokens", 1024),
top_p=kwargs.get("top_p", 1),
)
return raw_message.response
[build-system]
build-backend = "poetry.core.masonry.api"
requires = ["poetry-core"]
[tool.codespell]
check-filenames = true
check-hidden = true
skip = "*.csv,*.html,*.json,*.jsonl,*.pdf,*.txt,*.ipynb"
[tool.llamahub]
contains_example = false
import_path = "llama_index.llms.contextual"
[tool.llamahub.class_authors]
Contextual = "sean-smith"
[tool.mypy]
disallow_untyped_defs = true
exclude = ["_static", "build", "examples", "notebooks", "venv"]
ignore_missing_imports = true
python_version = "3.8"
[tool.poetry]
authors = ["Sean Smith <sean.smith@contextual.ai>"]
description = "llama-index contextual integration"
exclude = ["**/BUILD"]
license = "MIT"
name = "llama-index-llms-contextual"
readme = "README.md"
version = "0.0.1"
[tool.poetry.dependencies]
python = ">=3.9,<4.0"
llama-index-llms-openai-like = "^0.3.3"
contextual-client = "^0.4.0"
[tool.poetry.group.dev.dependencies.black]
extras = ["jupyter"]
version = "<=23.9.1,>=23.7.0"
[tool.poetry.group.dev.dependencies.codespell]
extras = ["toml"]
version = ">=v2.2.6"
[[tool.poetry.packages]]
include = "llama_index/"
python_sources()
from llama_index.core.base.llms.base import BaseLLM
from llama_index.llms.contextual import Contextual
def test_llm_class():
names_of_base_classes = [b.__name__ for b in Contextual.__mro__]
assert BaseLLM.__name__ in names_of_base_classes
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment