Skip to content

Commit 6ba3f55

Browse files
authored
Contextual Generate model (#17913)
1 parent 5e37074 commit 6ba3f55

File tree

10 files changed

+413
-0
lines changed

10 files changed

+413
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
poetry_requirements(
2+
name="poetry",
3+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Contextual LLM Integration for LlamaIndex
2+
3+
This package provides a Contextual LLM integration for LlamaIndex.
4+
5+
## Installation
6+
7+
```bash
8+
pip install llama-index-llms-contextual
9+
```
10+
11+
## Usage
12+
13+
```python
14+
from llama_index.llms.contextual import Contextual
15+
16+
llm = Contextual(model="contextual-clm", api_key="your_api_key")
17+
18+
response = llm.complete("Explain the importance of Grounded Language Models.")
19+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
python_sources()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from llama_index.llms.contextual.base import Contextual
2+
3+
__all__ = ["Contextual"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
from typing import Any, Optional
2+
3+
from llama_index.llms.openai_like import OpenAILike
4+
from pydantic import Field
5+
from typing import List
6+
from llama_index.core.llms.callbacks import (
7+
llm_chat_callback,
8+
llm_completion_callback,
9+
)
10+
from llama_index.core.base.llms.types import (
11+
CompletionResponse,
12+
ChatResponse,
13+
ChatResponseGen,
14+
MessageRole,
15+
ChatMessage,
16+
)
17+
18+
19+
from contextual import ContextualAI
20+
21+
22+
class Contextual(OpenAILike):
23+
"""
24+
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.
25+
26+
The total request cannot exceed 32,000 tokens. Email [email protected] with any feedback or questions.
27+
28+
Examples:
29+
`pip install llama-index-llms-contextual`
30+
31+
```python
32+
from llama_index.llms.contextual import Contextual
33+
34+
# Set up the Contextual class with the required model and API key
35+
llm = Contextual(model="contextual-clm", api_key="your_api_key")
36+
37+
# Call the complete method with a query
38+
response = llm.complete("Explain the importance of low latency LLMs")
39+
40+
print(response)
41+
```
42+
"""
43+
44+
model: str = Field(
45+
description="The model to use. Currently only supports `v1`.", default="v1"
46+
)
47+
api_key: str = Field(description="The API key to use.", default=None)
48+
base_url: str = Field(
49+
description="The base URL to use.",
50+
default="https://api.contextual.ai/v1/generate",
51+
)
52+
avoid_commentary: bool = Field(
53+
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.",
54+
default=False,
55+
)
56+
client: Any = Field(default=None, description="Contextual AI Client")
57+
58+
def __init__(
59+
self,
60+
model: str,
61+
api_key: str,
62+
base_url: str = None,
63+
avoid_commentary: bool = False,
64+
**openai_llm_kwargs: Any,
65+
) -> None:
66+
super().__init__(
67+
model=model,
68+
api_key=api_key,
69+
api_base=base_url,
70+
is_chat_model=openai_llm_kwargs.pop("is_chat_model", True),
71+
**openai_llm_kwargs,
72+
)
73+
74+
try:
75+
self.client = ContextualAI(api_key=api_key, base_url=base_url)
76+
except Exception as e:
77+
raise ValueError(f"Error initializing ContextualAI client: {e}")
78+
79+
@classmethod
80+
def class_name(cls) -> str:
81+
"""Get class name."""
82+
return "contextual-clm"
83+
84+
# Synchronous Methods
85+
@llm_completion_callback()
86+
def complete(
87+
self, prompt: str, knowledge: Optional[List[str]] = None, **kwargs
88+
) -> CompletionResponse:
89+
"""
90+
Generate completion for the given prompt.
91+
92+
Args:
93+
prompt (str): The input prompt to generate completion for.
94+
**kwargs: Additional keyword arguments for the API request.
95+
96+
Returns:
97+
str: The generated text completion.
98+
"""
99+
messages_list = [{"role": MessageRole.USER, "content": prompt}]
100+
response = self._generate(
101+
knowledge=knowledge,
102+
messages=messages_list,
103+
model=self.model,
104+
system_prompt=self.system_prompt,
105+
**kwargs,
106+
)
107+
return CompletionResponse(text=response)
108+
109+
@llm_chat_callback()
110+
def chat(self, messages: List[ChatMessage], **kwargs) -> ChatResponse:
111+
"""
112+
Generate a chat response for the given messages.
113+
"""
114+
messages_list = [
115+
{"role": msg.role, "content": msg.blocks[0].text} for msg in messages
116+
]
117+
response = self._generate(
118+
knowledge=kwargs.get("knowledge_base", None),
119+
messages=messages_list,
120+
model=self.model,
121+
system_prompt=self.system_prompt,
122+
**kwargs,
123+
)
124+
return ChatResponse(
125+
message=ChatMessage(role=MessageRole.ASSISTANT, content=response)
126+
)
127+
128+
@llm_chat_callback()
129+
def stream_chat(self, messages: List[ChatMessage], **kwargs) -> ChatResponseGen:
130+
"""
131+
Generate a chat response for the given messages.
132+
"""
133+
raise NotImplementedError("stream methods not implemented in Contextual")
134+
135+
@llm_completion_callback()
136+
def stream_complete(self, prompt: str, **kwargs) -> ChatResponseGen:
137+
"""
138+
Generate a chat response for the given messages.
139+
"""
140+
raise NotImplementedError("stream methods not implemented in Contextual")
141+
142+
# ===== Async Endpoints =====
143+
@llm_chat_callback()
144+
async def achat(
145+
self,
146+
messages: Sequence[ChatMessage],
147+
**kwargs: Any,
148+
) -> ChatResponse:
149+
raise NotImplementedError("async methods not implemented in Contextual")
150+
151+
@llm_chat_callback()
152+
async def astream_chat(
153+
self,
154+
messages: Sequence[ChatMessage],
155+
**kwargs: Any,
156+
) -> ChatResponseAsyncGen:
157+
raise NotImplementedError("async methods not implemented in Contextual")
158+
159+
@llm_completion_callback()
160+
async def acomplete(
161+
self, prompt: str, formatted: bool = False, **kwargs: Any
162+
) -> CompletionResponse:
163+
raise NotImplementedError("async methods not implemented in Contextual")
164+
165+
@llm_completion_callback()
166+
async def astream_complete(
167+
self, prompt: str, formatted: bool = False, **kwargs: Any
168+
) -> CompletionResponseAsyncGen:
169+
raise NotImplementedError("async methods not implemented in Contextual")
170+
171+
def _generate(
172+
self, knowledge, messages, system_prompt, **kwargs
173+
) -> CompletionResponse:
174+
"""
175+
Generate completion for the given prompt.
176+
"""
177+
raw_message = self.client.generate.create(
178+
messages=messages,
179+
knowledge=knowledge or [],
180+
model=self.model,
181+
system_prompt=system_prompt,
182+
avoid_commentary=self.avoid_commentary,
183+
temperature=kwargs.get("temperature", 0.0),
184+
max_new_tokens=kwargs.get("max_tokens", 1024),
185+
top_p=kwargs.get("top_p", 1),
186+
)
187+
return raw_message.response

0 commit comments

Comments
 (0)