Configurable conversation limit now set to 10 exchanges. This helps when you want to manually continue a thread of thought across different models manually.
This commit is contained in:
@@ -92,6 +92,12 @@ DEFAULT_THINKING_MODE_THINKDEEP=high
|
||||
# Defaults to 3 hours if not specified
|
||||
CONVERSATION_TIMEOUT_HOURS=3
|
||||
|
||||
# Optional: Max conversation turns
|
||||
# Maximum number of turns allowed in an AI-to-AI conversation thread
|
||||
# Each exchange (Claude asks, Gemini responds) counts as 2 turns
|
||||
# So 20 turns = 10 exchanges. Defaults to 20 if not specified
|
||||
MAX_CONVERSATION_TURNS=20
|
||||
|
||||
# Optional: Logging level (DEBUG, INFO, WARNING, ERROR)
|
||||
# DEBUG: Shows detailed operational messages for troubleshooting (default)
|
||||
# INFO: Shows general operational messages
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -166,3 +166,6 @@ test_simulation_files/.claude/
|
||||
|
||||
# Temporary test directories
|
||||
test-setup/
|
||||
|
||||
# Scratch feature documentation files
|
||||
FEATURE_*.md
|
||||
|
||||
@@ -470,7 +470,7 @@ This server enables **true AI collaboration** between Claude and multiple AI mod
|
||||
- **Asynchronous workflow**: Conversations don't need to be sequential - Claude can work on tasks between exchanges, then return to Gemini with additional context and progress updates
|
||||
- **Incremental updates**: Share only new information in each exchange while maintaining full conversation history
|
||||
- **Automatic 25K limit bypass**: Each exchange sends only incremental context, allowing unlimited total conversation size
|
||||
- Up to 5 exchanges per conversation with 3-hour expiry (configurable)
|
||||
- Up to 10 exchanges per conversation (configurable via `MAX_CONVERSATION_TURNS`) with 3-hour expiry (configurable via `CONVERSATION_TIMEOUT_HOURS`)
|
||||
- Thread-safe with Redis persistence across all tools
|
||||
|
||||
**Cross-tool & Cross-Model Continuation Example:**
|
||||
|
||||
@@ -41,6 +41,7 @@ services:
|
||||
- DEFAULT_MODEL=${DEFAULT_MODEL:-auto}
|
||||
- DEFAULT_THINKING_MODE_THINKDEEP=${DEFAULT_THINKING_MODE_THINKDEEP:-high}
|
||||
- CONVERSATION_TIMEOUT_HOURS=${CONVERSATION_TIMEOUT_HOURS:-3}
|
||||
- MAX_CONVERSATION_TURNS=${MAX_CONVERSATION_TURNS:-20}
|
||||
# Model usage restrictions
|
||||
- OPENAI_ALLOWED_MODELS=${OPENAI_ALLOWED_MODELS:-}
|
||||
- GOOGLE_ALLOWED_MODELS=${GOOGLE_ALLOWED_MODELS:-}
|
||||
|
||||
@@ -146,8 +146,8 @@ class TestClaudeContinuationOffers:
|
||||
# Should still offer continuation since turns remain
|
||||
assert response_data["status"] == "continuation_available"
|
||||
assert "continuation_offer" in response_data
|
||||
# 10 max - 2 existing - 1 new = 7 remaining
|
||||
assert response_data["continuation_offer"]["remaining_turns"] == 7
|
||||
# MAX_CONVERSATION_TURNS - 2 existing - 1 new = remaining
|
||||
assert response_data["continuation_offer"]["remaining_turns"] == MAX_CONVERSATION_TURNS - 3
|
||||
|
||||
@patch("utils.conversation_memory.get_redis_client")
|
||||
@patch.dict("os.environ", {"PYTEST_CURRENT_TEST": ""}, clear=False)
|
||||
@@ -267,10 +267,10 @@ I'd be happy to examine the error handling patterns in more detail if that would
|
||||
# Parse response
|
||||
response_data = json.loads(response[0].text)
|
||||
|
||||
# Should offer continuation since there are remaining turns (9 remaining: 10 max - 0 current - 1)
|
||||
# Should offer continuation since there are remaining turns (MAX - 0 current - 1)
|
||||
assert response_data["status"] == "continuation_available"
|
||||
assert response_data.get("continuation_offer") is not None
|
||||
assert response_data["continuation_offer"]["remaining_turns"] == 9
|
||||
assert response_data["continuation_offer"]["remaining_turns"] == MAX_CONVERSATION_TURNS - 1
|
||||
|
||||
@patch("utils.conversation_memory.get_redis_client")
|
||||
@patch.dict("os.environ", {"PYTEST_CURRENT_TEST": ""}, clear=False)
|
||||
@@ -465,8 +465,8 @@ class TestContinuationIntegration:
|
||||
# Should still offer continuation if there are remaining turns
|
||||
assert response_data2["status"] == "continuation_available"
|
||||
assert "continuation_offer" in response_data2
|
||||
# 10 max - 1 existing - 1 new = 8 remaining
|
||||
assert response_data2["continuation_offer"]["remaining_turns"] == 8
|
||||
# MAX_CONVERSATION_TURNS - 1 existing - 1 new = remaining
|
||||
assert response_data2["continuation_offer"]["remaining_turns"] == MAX_CONVERSATION_TURNS - 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -57,7 +57,17 @@ from pydantic import BaseModel
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Configuration constants
|
||||
MAX_CONVERSATION_TURNS = 10 # Maximum turns allowed per conversation thread
|
||||
# Get max conversation turns from environment, default to 20 turns (10 exchanges)
|
||||
try:
|
||||
MAX_CONVERSATION_TURNS = int(os.getenv("MAX_CONVERSATION_TURNS", "20"))
|
||||
if MAX_CONVERSATION_TURNS <= 0:
|
||||
logger.warning(f"Invalid MAX_CONVERSATION_TURNS value ({MAX_CONVERSATION_TURNS}), using default of 20 turns")
|
||||
MAX_CONVERSATION_TURNS = 20
|
||||
except ValueError:
|
||||
logger.warning(
|
||||
f"Invalid MAX_CONVERSATION_TURNS value ('{os.getenv('MAX_CONVERSATION_TURNS')}'), using default of 20 turns"
|
||||
)
|
||||
MAX_CONVERSATION_TURNS = 20
|
||||
|
||||
# Get conversation timeout from environment (in hours), default to 3 hours
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user