Skip to content

Commit

Permalink
adds support for o1 (non-preview) model for openai_client, improves h…
Browse files Browse the repository at this point in the history
…andling of context for codespace-assistant (#308)

NOTE: suggested that you re-run root level `make` if merging this update
into your environment where you already have your packages installed, in
order to cause the updated `openai` and `tiktoken` packages to be
loaded.
  • Loading branch information
bkrabach authored Jan 28, 2025
1 parent ad01222 commit 754432f
Show file tree
Hide file tree
Showing 52 changed files with 5,046 additions and 1,777 deletions.
2 changes: 1 addition & 1 deletion assistants/codespace-assistant/assistant/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class AssistantConfigModel(BaseModel):
AzureOpenAIClientConfigModel | OpenAIClientConfigModel,
Field(
title="OpenAI Reasoning Model Configuration",
description="Configuration for the reasoning model, such as o1-preview, o1-mini, etc.",
description="Configuration for the reasoning model, such as o1, o1-preview, o1-mini, etc.",
discriminator="ai_service_type",
default=AzureOpenAIClientConfigModel.model_construct(),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,34 @@
prompt=dedent("""
Follow these steps for each interaction:
1. User Identification:
- You should assume that you are interacting with default_user
- If you have not identified default_user, proactively try to do so.
2. Memory Retrieval:
- Always begin your chat by saying only "Remembering..." and retrieve all relevant information from your knowledge graph
1. Memory Retrieval:
- Always begin your chat by saying only "Remembering..." and retrieve all relevant information
from your knowledge graph
- Always refer to your knowledge graph as your "memory"
3. Memory
2. Memory
- While conversing with the user, be attentive to any new information that falls into these categories:
a) Basic Identity (age, gender, location, job title, education level, etc.)
b) Behaviors (interests, habits, etc.)
c) Preferences (communication style, preferred language, etc.)
d) Goals (goals, targets, aspirations, etc.)
e) Relationships (personal and professional relationships up to 3 degrees of separation)
4. Memory Update:
3. Memory Update:
- If any new information was gathered during the interaction, update your memory as follows:
a) Create entities for recurring organizations, people, and significant events
b) Connect them to the current entities using relations
b) Store facts about them as observations
"""),
),
MCPServerConfig(
name="Web Research MCP Server",
command="npx",
args=["-y", "@mzxrai/mcp-webresearch@latest"],
),
# MCPServerConfig(
# name="Sequential Thinking MCP Server",
# command="npx",
# args=["-y", "@modelcontextprotocol/server-sequential-thinking"],
# ),
# MCPServerConfig(
# name="Web Research MCP Server",
# command="npx",
# args=["-y", "@mzxrai/mcp-webresearch@latest"],
# ),
]
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async def handle_completion(
context: ConversationContext,
config: AssistantConfigModel,
silence_token: str,
method_metadata_key: str,
metadata_key: str,
response_start_time: float,
) -> StepResult:
# helper function for handling errors
Expand Down Expand Up @@ -90,7 +90,7 @@ async def handle_error(error_message: str) -> StepResult:
step_result.metadata,
{
"debug": {
method_metadata_key: {
metadata_key: {
"response": completion.model_dump() if completion else "[no response from openai]",
},
},
Expand Down Expand Up @@ -163,7 +163,7 @@ async def handle_error(error_message: str) -> StepResult:
mcp_sessions,
tool_call,
mcp_tools,
f"{method_metadata_key}:request:tool_call_{tool_call_count}",
f"{metadata_key}:request:tool_call_{tool_call_count}",
)
except Exception as e:
logger.exception(f"Error handling tool call: {e}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ async def respond_to_conversation(

# Initialize a loop control variable
max_steps = config.extensions_config.tools.max_steps
encountered_error = False
completed_within_max_steps = False
step_count = 0

Expand All @@ -69,14 +70,19 @@ async def respond_to_conversation(
context=context,
config=config,
metadata=metadata,
metadata_key=f"respond_to_conversation:step_{step_count}",
)

if step_result.status == "error":
encountered_error = True
break

if step_result.status == "final":
completed_within_max_steps = True
break

# If the conversation did not complete within the maximum number of steps, send a message to the user
if not completed_within_max_steps:
if not completed_within_max_steps and not encountered_error:
await context.send_messages(
NewConversationMessage(
content=config.extensions_config.tools.max_steps_truncation_message,
Expand Down
33 changes: 26 additions & 7 deletions assistants/codespace-assistant/assistant/response/step_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,23 @@ async def next_step(
context: ConversationContext,
config: AssistantConfigModel,
metadata: dict[str, Any],
metadata_key: str,
) -> StepResult:
step_result = StepResult(status="continue", metadata=metadata.copy())

# helper function for handling errors
async def handle_error(error_message: str) -> StepResult:
async def handle_error(error_message: str, error_debug: dict[str, Any] | None = None) -> StepResult:
if error_debug is not None:
deepmerge.always_merger.merge(
step_result.metadata,
{
"debug": {
metadata_key: {
"error": error_debug,
},
},
},
)
await context.send_messages(
NewConversationMessage(
content=error_message,
Expand All @@ -63,9 +75,6 @@ async def handle_error(error_message: str) -> StepResult:
# )
# reasoning_request_config = config.reasoning_ai_client_config.request_config

# Define the metadata key for any metadata created within this method
method_metadata_key = "respond_to_conversation"

# Track the start time of the response generation
response_start_time = time.time()

Expand All @@ -92,7 +101,7 @@ async def handle_error(error_message: str) -> StepResult:
step_result.metadata,
{
"debug": {
method_metadata_key: {
metadata_key: {
"request": {
"model": generative_request_config.model,
"messages": chat_message_params,
Expand All @@ -111,12 +120,22 @@ async def handle_error(error_message: str) -> StepResult:

except Exception as e:
logger.exception(f"exception occurred calling openai chat completion: {e}")
deepmerge.always_merger.merge(
step_result.metadata,
{
"debug": {
metadata_key: {
"error": str(e),
},
},
},
)
await context.send_messages(
NewConversationMessage(
content="An error occurred while calling the OpenAI API. Is it configured correctly?"
" View the debug inspector for more information.",
message_type=MessageType.notice,
metadata={method_metadata_key: {"error": str(e)}},
metadata=step_result.metadata,
)
)
step_result.status = "error"
Expand All @@ -133,7 +152,7 @@ async def handle_error(error_message: str) -> StepResult:
context,
config,
silence_token,
method_metadata_key,
metadata_key,
response_start_time,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def convert_mcp_tools_to_openai_tools(mcp_tools: List[Tool] | None) -> List[Chat
"properties": {
"aiContext": aiContext,
},
"required": ["aiContext"],
},
),
),
Expand Down
3 changes: 2 additions & 1 deletion assistants/codespace-assistant/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ dependencies = [
"html2docx>=1.6.0",
"markdown>=3.6",
"mcp>=1.2.0",
"openai>=1.3.9",
"openai>=1.60.2",
"openai-client>=0.1.0",
"tiktoken>=0.8.0",
]

[tool.hatch.build.targets.wheel]
Expand Down
54 changes: 28 additions & 26 deletions assistants/codespace-assistant/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 754432f

Please sign in to comment.