-
Notifications
You must be signed in to change notification settings - Fork 878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrade Opengpts #361
Upgrade Opengpts #361
Changes from all commits
cbbda36
594d9cd
9e3bbd4
aacf3db
5f8f2e1
4f151db
7483722
23b0f2a
27f1df2
538f46f
34bc8a1
024ae14
5ca17e2
495ee01
5118662
a310032
005dde7
22721fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,26 @@ | ||
# backend | ||
|
||
## Database Migrations | ||
|
||
### Migration 5 - Checkpoint Management Update | ||
This migration introduces a significant change to thread checkpoint management: | ||
|
||
#### Changes | ||
- Transitions from single-table pickle storage to a robust multi-table checkpoint management system | ||
- Implements LangGraph's latest checkpoint architecture for improved state persistence | ||
- Preserves existing checkpoint data by renaming `checkpoints` table to `old_checkpoints` | ||
- Introduces three new tables for better checkpoint management: | ||
- `checkpoints`: Core checkpoint metadata | ||
- `checkpoint_blobs`: Actual checkpoint data storage (compatible with LangGraph state serialization) | ||
- `checkpoint_writes`: Tracks checkpoint write operations | ||
- Adds runtime initialization via `ensure_setup()` in the lifespan event | ||
|
||
#### Impact | ||
- **Breaking Change**: Historical threads/checkpoints (pre-migration) will not be accessible in the UI | ||
- Previous checkpoint data remains preserved but inaccessible in the new system | ||
- Designed to work seamlessly with LangGraph's state persistence requirements | ||
|
||
#### Migration Details | ||
- **Up Migration**: Safely preserves existing data by renaming the table | ||
- **Down Migration**: Restores original table structure if needed | ||
- New checkpoint management tables are automatically created at application startup |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
import pickle | ||
from enum import Enum | ||
from typing import Any, Dict, Mapping, Optional, Sequence, Union | ||
|
||
|
@@ -7,14 +6,13 @@ | |
ConfigurableField, | ||
RunnableBinding, | ||
) | ||
from langgraph.checkpoint import CheckpointAt | ||
from langgraph.graph.message import Messages | ||
from langgraph.pregel import Pregel | ||
|
||
from app.agent_types.tools_agent import get_tools_agent_executor | ||
from app.agent_types.xml_agent import get_xml_agent_executor | ||
from app.chatbot import get_chatbot_executor | ||
from app.checkpoint import PostgresCheckpoint | ||
from app.checkpoint import AsyncPostgresCheckpoint | ||
from app.llms import ( | ||
get_anthropic_llm, | ||
get_google_llm, | ||
|
@@ -74,7 +72,7 @@ class AgentType(str, Enum): | |
|
||
DEFAULT_SYSTEM_MESSAGE = "You are a helpful assistant." | ||
|
||
CHECKPOINTER = PostgresCheckpoint(serde=pickle, at=CheckpointAt.END_OF_STEP) | ||
CHECKPOINTER = AsyncPostgresCheckpoint() | ||
|
||
|
||
def get_agent_executor( | ||
|
@@ -123,7 +121,6 @@ def get_agent_executor( | |
return get_tools_agent_executor( | ||
tools, llm, system_message, interrupt_before_action, CHECKPOINTER | ||
) | ||
|
||
else: | ||
raise ValueError("Unexpected agent type") | ||
|
||
|
@@ -135,7 +132,7 @@ class ConfigurableAgent(RunnableBinding): | |
retrieval_description: str = RETRIEVAL_DESCRIPTION | ||
interrupt_before_action: bool = False | ||
assistant_id: Optional[str] = None | ||
thread_id: Optional[str] = None | ||
thread_id: Optional[str] = "" | ||
user_id: Optional[str] = None | ||
|
||
def __init__( | ||
|
@@ -145,7 +142,7 @@ def __init__( | |
agent: AgentType = AgentType.GPT_35_TURBO, | ||
system_message: str = DEFAULT_SYSTEM_MESSAGE, | ||
assistant_id: Optional[str] = None, | ||
thread_id: Optional[str] = None, | ||
thread_id: Optional[str] = "", | ||
retrieval_description: str = RETRIEVAL_DESCRIPTION, | ||
interrupt_before_action: bool = False, | ||
kwargs: Optional[Mapping[str, Any]] = None, | ||
|
@@ -204,7 +201,9 @@ def get_chatbot( | |
if llm_type == LLMType.GPT_35_TURBO: | ||
llm = get_openai_llm() | ||
elif llm_type == LLMType.GPT_4: | ||
llm = get_openai_llm(gpt_4=True) | ||
llm = get_openai_llm(model="gpt-4") | ||
elif llm_type == LLMType.GPT_4O: | ||
llm = get_openai_llm(model="gpt-4o") | ||
elif llm_type == LLMType.AZURE_OPENAI: | ||
llm = get_openai_llm(azure=True) | ||
elif llm_type == LLMType.CLAUDE2: | ||
|
@@ -265,7 +264,7 @@ class ConfigurableRetrieval(RunnableBinding): | |
llm_type: LLMType | ||
system_message: str = DEFAULT_SYSTEM_MESSAGE | ||
assistant_id: Optional[str] = None | ||
thread_id: Optional[str] = None | ||
thread_id: Optional[str] = "" | ||
user_id: Optional[str] = None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this not a None default? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I spent a lot of time debugging this part. The error indicates a conflict in the configuration specifications for The error occurs during validation in the following code: @router.get("/config_schema")
async def config_schema() -> dict:
"""Return the config schema of the runnable."""
return agent.config_schema().model_json_schema() The issue seems to arise because there are two conflicting ConfigurableFieldSpec definitions for thread_id: So, I decided to set the default to '', and it works. However, I would prefer to keep it as None. Do you know what might be causing the problem? The |
||
|
||
def __init__( | ||
|
@@ -274,7 +273,7 @@ def __init__( | |
llm_type: LLMType = LLMType.GPT_35_TURBO, | ||
system_message: str = DEFAULT_SYSTEM_MESSAGE, | ||
assistant_id: Optional[str] = None, | ||
thread_id: Optional[str] = None, | ||
thread_id: Optional[str] = "", | ||
kwargs: Optional[Mapping[str, Any]] = None, | ||
config: Optional[Mapping[str, Any]] = None, | ||
**others: Any, | ||
|
@@ -319,7 +318,9 @@ def __init__( | |
assistant_id=ConfigurableField( | ||
id="assistant_id", name="Assistant ID", is_shared=True | ||
), | ||
thread_id=ConfigurableField(id="thread_id", name="Thread ID", is_shared=True), | ||
thread_id=ConfigurableField( | ||
id="thread_id", name="Thread ID", annotation=str, is_shared=True | ||
), | ||
) | ||
.with_types( | ||
input_type=Dict[str, Any], | ||
|
@@ -335,7 +336,7 @@ def __init__( | |
system_message=DEFAULT_SYSTEM_MESSAGE, | ||
retrieval_description=RETRIEVAL_DESCRIPTION, | ||
assistant_id=None, | ||
thread_id=None, | ||
thread_id="", | ||
) | ||
.configurable_fields( | ||
agent=ConfigurableField(id="agent_type", name="Agent Type"), | ||
|
@@ -348,7 +349,9 @@ def __init__( | |
assistant_id=ConfigurableField( | ||
id="assistant_id", name="Assistant ID", is_shared=True | ||
), | ||
thread_id=ConfigurableField(id="thread_id", name="Thread ID", is_shared=True), | ||
thread_id=ConfigurableField( | ||
id="thread_id", name="Thread ID", annotation=str, is_shared=True | ||
), | ||
tools=ConfigurableField(id="tools", name="Tools"), | ||
retrieval_description=ConfigurableField( | ||
id="retrieval_description", name="Retrieval Description" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this not a None?