참고소스 수정본
This commit is contained in:
185
참고/instructor-main/instructor/providers/xai/utils.py
Normal file
185
참고/instructor-main/instructor/providers/xai/utils.py
Normal file
@@ -0,0 +1,185 @@
|
||||
"""xAI-specific utilities.
|
||||
|
||||
This module contains utilities specific to the xAI provider,
|
||||
including reask functions, response handlers, and message formatting.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
from ...mode import Mode
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from xai_sdk import chat as xchat
|
||||
else:
|
||||
try:
|
||||
from xai_sdk import chat as xchat
|
||||
except ImportError:
|
||||
xchat = None
|
||||
|
||||
|
||||
def _convert_messages(messages: list[dict[str, Any]]):
|
||||
"""Convert OpenAI-style messages to xAI format."""
|
||||
if xchat is None:
|
||||
from ...core.exceptions import ConfigurationError
|
||||
|
||||
raise ConfigurationError(
|
||||
"The xAI provider needs the optional dependency `xai-sdk`. "
|
||||
'Install it with `uv pip install "instructor[xai]"` (or `pip install "instructor[xai]"`). '
|
||||
"Note: xai-sdk requires Python 3.10+."
|
||||
) from None
|
||||
|
||||
converted = []
|
||||
for m in messages:
|
||||
role = m["role"]
|
||||
content = m.get("content", "")
|
||||
if isinstance(content, str):
|
||||
c = xchat.text(content)
|
||||
else:
|
||||
raise ValueError("Only string content supported for xAI provider")
|
||||
if role == "user":
|
||||
converted.append(xchat.user(c))
|
||||
elif role == "assistant":
|
||||
converted.append(xchat.assistant(c))
|
||||
elif role == "system":
|
||||
converted.append(xchat.system(c))
|
||||
elif role == "tool":
|
||||
converted.append(xchat.tool_result(content))
|
||||
else:
|
||||
raise ValueError(f"Unsupported role: {role}")
|
||||
return converted
|
||||
|
||||
|
||||
def reask_xai_json(
|
||||
kwargs: dict[str, Any],
|
||||
response: Any,
|
||||
exception: Exception,
|
||||
):
|
||||
"""
|
||||
Handle reask for xAI JSON mode when validation fails.
|
||||
|
||||
Kwargs modifications:
|
||||
- Modifies: "messages" (appends user message requesting correction)
|
||||
"""
|
||||
kwargs = kwargs.copy()
|
||||
reask_msg = {
|
||||
"role": "user",
|
||||
"content": f"Validation Errors found:\n{exception}\nRecall the function correctly, fix the errors found in the following attempt:\n{response}",
|
||||
}
|
||||
kwargs["messages"].append(reask_msg)
|
||||
return kwargs
|
||||
|
||||
|
||||
def reask_xai_tools(
|
||||
kwargs: dict[str, Any],
|
||||
response: Any,
|
||||
exception: Exception,
|
||||
):
|
||||
"""
|
||||
Handle reask for xAI tools mode when validation fails.
|
||||
|
||||
Kwargs modifications:
|
||||
- Modifies: "messages" (appends assistant and user messages for tool correction)
|
||||
"""
|
||||
kwargs = kwargs.copy()
|
||||
|
||||
# Add assistant response to conversation history
|
||||
assistant_msg = {
|
||||
"role": "assistant",
|
||||
"content": str(response),
|
||||
}
|
||||
kwargs["messages"].append(assistant_msg)
|
||||
|
||||
# Add user correction request
|
||||
reask_msg = {
|
||||
"role": "user",
|
||||
"content": f"Validation Error found:\n{exception}\nRecall the function correctly, fix the errors",
|
||||
}
|
||||
kwargs["messages"].append(reask_msg)
|
||||
return kwargs
|
||||
|
||||
|
||||
def handle_xai_json(
|
||||
response_model: type[Any] | None, new_kwargs: dict[str, Any]
|
||||
) -> tuple[type[Any] | None, dict[str, Any]]:
|
||||
"""
|
||||
Handle xAI JSON mode.
|
||||
|
||||
When response_model is None:
|
||||
- Converts messages from OpenAI format to xAI format
|
||||
- No schema is added to the request
|
||||
|
||||
When response_model is provided:
|
||||
- Converts messages from OpenAI format to xAI format
|
||||
- Sets up the model for JSON parsing mode
|
||||
|
||||
Kwargs modifications:
|
||||
- Modifies: "messages" (converts from OpenAI to xAI format)
|
||||
- Removes: instructor-specific kwargs (max_retries, validation_context, context, hooks)
|
||||
"""
|
||||
# Convert messages to xAI format
|
||||
messages = new_kwargs.get("messages", [])
|
||||
new_kwargs["x_messages"] = _convert_messages(messages)
|
||||
|
||||
# Remove instructor-specific kwargs that xAI doesn't support
|
||||
new_kwargs.pop("max_retries", None)
|
||||
new_kwargs.pop("validation_context", None)
|
||||
new_kwargs.pop("context", None)
|
||||
new_kwargs.pop("hooks", None)
|
||||
|
||||
return response_model, new_kwargs
|
||||
|
||||
|
||||
def handle_xai_tools(
|
||||
response_model: type[Any] | None, new_kwargs: dict[str, Any]
|
||||
) -> tuple[type[Any] | None, dict[str, Any]]:
|
||||
"""
|
||||
Handle xAI tools mode.
|
||||
|
||||
When response_model is None:
|
||||
- Converts messages from OpenAI format to xAI format
|
||||
- No tools are configured
|
||||
|
||||
When response_model is provided:
|
||||
- Converts messages from OpenAI format to xAI format
|
||||
- Sets up tool schema from the response model
|
||||
- Configures tool choice for automatic tool selection
|
||||
|
||||
Kwargs modifications:
|
||||
- Modifies: "messages" (converts from OpenAI to xAI format)
|
||||
- Adds: "tool" (xAI tool schema) - only when response_model provided
|
||||
- Removes: instructor-specific kwargs (max_retries, validation_context, context, hooks)
|
||||
"""
|
||||
# Convert messages to xAI format
|
||||
messages = new_kwargs.get("messages", [])
|
||||
new_kwargs["x_messages"] = _convert_messages(messages)
|
||||
|
||||
# Remove instructor-specific kwargs that xAI doesn't support
|
||||
new_kwargs.pop("max_retries", None)
|
||||
new_kwargs.pop("validation_context", None)
|
||||
new_kwargs.pop("context", None)
|
||||
new_kwargs.pop("hooks", None)
|
||||
|
||||
if response_model is not None and xchat is not None:
|
||||
# Set up tool schema for structured output
|
||||
new_kwargs["tool"] = xchat.tool(
|
||||
name=response_model.__name__,
|
||||
description=response_model.__doc__ or "",
|
||||
parameters=response_model.model_json_schema(),
|
||||
)
|
||||
|
||||
return response_model, new_kwargs
|
||||
|
||||
|
||||
# Handler registry for xAI
|
||||
XAI_HANDLERS = {
|
||||
Mode.XAI_JSON: {
|
||||
"reask": reask_xai_json,
|
||||
"response": handle_xai_json,
|
||||
},
|
||||
Mode.XAI_TOOLS: {
|
||||
"reask": reask_xai_tools,
|
||||
"response": handle_xai_tools,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user