Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gptcli/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.3.2"
__version__ = "0.3.3"
3 changes: 3 additions & 0 deletions gptcli/assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from gptcli.providers.anthropic import AnthropicCompletionProvider
from gptcli.providers.cohere import CohereCompletionProvider
from gptcli.providers.azure_openai import AzureOpenAICompletionProvider
from gptcli.providers.xai import XAICompletionProvider


class AssistantConfig(TypedDict, total=False):
Expand Down Expand Up @@ -93,6 +94,8 @@ def get_completion_provider(
return CohereCompletionProvider()
elif model.startswith("gemini"):
return GoogleCompletionProvider()
elif model.startswith("grok"):
return XAICompletionProvider()
else:
raise ValueError(f"Unknown model: {model}")

Expand Down
1 change: 1 addition & 0 deletions gptcli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class GptCliConfig:
anthropic_api_key: Optional[str] = os.environ.get("ANTHROPIC_API_KEY")
google_api_key: Optional[str] = os.environ.get("GOOGLE_API_KEY")
cohere_api_key: Optional[str] = os.environ.get("COHERE_API_KEY")
xai_api_key: Optional[str] = os.environ.get("XAI_API_KEY")
log_file: Optional[str] = None
log_level: str = "INFO"
assistants: Dict[str, AssistantConfig] = {}
Expand Down
3 changes: 3 additions & 0 deletions gptcli/gpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ def main():
if config.cohere_api_key:
gptcli.providers.cohere.api_key = config.cohere_api_key

if config.xai_api_key:
gptcli.providers.xai.api_key = config.xai_api_key

if config.google_api_key:
genai.configure(api_key=config.google_api_key)

Expand Down
6 changes: 4 additions & 2 deletions gptcli/providers/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def complete(
):
yield MessageDeltaEvent(response.choices[0].delta.content)

if response.usage and (pricing := gpt_pricing(args["model"])):
if response.usage and (pricing := self.pricing(args["model"])):
yield UsageEvent.with_pricing(
prompt_tokens=response.usage.prompt_tokens,
completion_tokens=response.usage.completion_tokens,
Expand All @@ -73,7 +73,7 @@ def complete(
next_choice = response.choices[0]
if next_choice.message.content:
yield MessageDeltaEvent(next_choice.message.content)
if response.usage and (pricing := gpt_pricing(args["model"])):
if response.usage and (pricing := self.pricing(args["model"])):
yield UsageEvent.with_pricing(
prompt_tokens=response.usage.prompt_tokens,
completion_tokens=response.usage.completion_tokens,
Expand All @@ -86,6 +86,8 @@ def complete(
except openai.APIError as e:
raise CompletionError(e.message) from e

def pricing(self, model: str) -> Optional[Pricing]:
return gpt_pricing(model)

GPT_3_5_TURBO_PRICE_PER_TOKEN: Pricing = {
"prompt": 0.50 / 1_000_000,
Expand Down
33 changes: 33 additions & 0 deletions gptcli/providers/xai.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os
from typing import Optional

from openai import OpenAI

from gptcli.completion import Pricing
from gptcli.providers.openai import OpenAICompletionProvider

api_key = os.environ.get("XAI_API_KEY")


class XAICompletionProvider(OpenAICompletionProvider):
def __init__(self):
self.client = OpenAI(api_key=api_key, base_url="https://api.x.ai/v1")

def pricing(self, model: str) -> Optional[Pricing]:
if model.startswith("grok-beta"):
return GROK_BETA_PRICE_PER_TOKEN
elif model.startswith("grok-2"):
return GROK_2_PRICE_PER_TOKEN
else:
return None


GROK_2_PRICE_PER_TOKEN: Pricing = {
"prompt": 2.00 / 1_000_000,
"response": 10.00 / 1_000_000,
}

GROK_BETA_PRICE_PER_TOKEN: Pricing = {
"prompt": 5.00 / 1_000_000,
"response": 15.00 / 1_000_000,
}
Loading