Advanced working with Chat Sessions#
Chat sessions in DecisionAI maintain state between the client and server. Understanding how to work with this state is key to effectively using the system.
The state is represented by the ChatSessionState class, which provides a comprehensive interface for managing the session. For complete API details, see Chat Session State.
Session State Management#
The chat session maintains state including:
Variables and their properties
Constraints and their status
Objective function
Model configuration
All of these components are accessible through properties and methods of the ChatSessionState class.
Accessing State#
Use the remote_state context manager to safely access and modify session state.
When using the remote_state context manager, the following happens:
Fetching the current state from the server
Providing a safe environment for modifications
Syncing changes back to the server when exiting the context
This ensures your local changes are properly propagated and maintains consistency between client and server.
with chat_session.remote_state() as state: # state is a ChatSessionState instance
# Access state properties
py_class_name = state.py_class_name
constraints = state.constraints
variables = state.variables
The state context manager ensures thread-safe access and proper synchronization with the server.
Variables and Constraints#
The session provides methods to manage variables and constraints programmatically:
Variables#
with chat_session.remote_state() as state:
# Get variable information
base_vars = state.base_variable_ids
user_vars = state.user_variable_ids
var_descriptions = state.variable_descriptions
# Check variable status
is_enabled = state.is_variable_enabled("var_id")
# Modify variables
state.disable_variable("var_id")
state.enable_variable("var_id")
Constraints#
with chat_session.remote_state() as state:
# Get constraint information
base_constraints = state.base_constraint_ids
user_constraints = state.user_constraint_ids
constraint_descriptions = state.constraint_descriptions
# Access constraint details
code = state.get_constraint_code("constraint_id")
formulation = state.get_constraint_formulation("constraint_id")
# Check constraint status
is_enabled = state.is_constraint_enabled("constraint_id")
# Modify constraints
state.disable_constraint("constraint_id")
state.enable_constraint("constraint_id")
Changing input data for a chat session#
You can replace the input data associated with a chat session at any time using the set_opt_input_data method. This is useful when you need to re-run the model with different parameters or updated datasets.
Calling set_opt_input_data performs the following actions:
Uploads the new InputData object to the server.
Updates the chat session to reference the new input data ID.
Automatically triggers a validation process to check compatibility with existing constraints (see next section).
# Assume 'chat_session' is an existing ChatSession instance
# and 'new_input_data' is an InputData object
chat_session.set_opt_input_data(new_input_data)
Validating compatibility of constraints with new input data#
When you change the input data using set_opt_input_data, the system automatically validates whether the existing constraints are compatible with the new data. This is done by attempting to formulate the optimization model using the new data and the current set of constraints.
If a constraint causes an error during formulation (e.g., referencing data that no longer exists or has changed structure), it is marked as “incompatible”.
Important: Incompatible constraints are not automatically disabled. You need to manually review and disable them if necessary using the remote_state context manager.
# After calling chat_session.set_opt_input_data(new_input_data)
with chat_session.remote_state() as state:
incompatible_ids = state.incompatible_constraint_ids
if incompatible_ids:
print(f"Found incompatible constraints: {incompatible_ids}")
# Decide how to handle them, e.g., disable them
for constraint_id in incompatible_ids:
print(f"Disabling incompatible constraint: {constraint_id}")
state.disable_constraint(constraint_id)
else:
print("All constraints are compatible with the new input data.")
This ensures that you are aware of potential issues arising from data changes and can decide how to proceed, whether by modifying the constraint, disabling it, or adjusting the input data further.
Advanced Features#
Soft Constraints and Priorities
Set constraint priorities to control soft constraint behavior:
with chat_session.remote_state() as state:
# Set constraint priority
state.set_constraint_priority("constraint_id", "A") # Priority A
state.set_constraint_priority("constraint_id", "B") # Priority B
state.set_constraint_priority("constraint_id", "C") # Priority C
state.set_constraint_priority("constraint_id", "hard") # Hard constraint
# Get constraint priority
priority = state.get_constraint_priority("constraint_id")
# Solve with current constraint priorities
solution = chat_session.solve()
Mathematical Formulation
Access the complete mathematical representation:
with chat_session.remote_state() as state:
# Get complete mathematical formulation
math_form = state.get_mathematical_formulation()
summary = state.executive_summary
Model Notations
Access and modify model notations:
with chat_session.remote_state() as state:
# Access variable notations
var_notations = state.variable_notations
# Access input notations
input_notations = state.input_notations
Monitoring Solve Operations#
You can monitor solve operations in real-time by providing a callback function to the connect() method. This is useful for tracking solve results, handling errors, or implementing custom logging.
Callback Signature
The callback function receives two parameters:
solution: Solution | None- The solution object when solve succeeds,Nonewhen it failserror: Exception | None- The exception when solve fails,Nonewhen it succeeds
Basic Usage
Use the callback to monitor solve operations during chat interactions:
def my_solve_monitor(solution, error):
if error:
print(f"Solve failed: {error}")
else:
print(f"Solution status: {solution.status}")
async with chat_session.connect(post_solve_callback=my_solve_monitor) as chat:
async for message in chat.stream_messages("Solve the model and present the solution"):
print(message)
When to Use Callbacks
Use solve callbacks when you need to:
Monitor solve success/failure/infeasibility rates during development
Implement custom logging or alerting for solve operations
Collect solve statistics for performance analysis
Handle solve errors in automated workflows
Store solution history for comparison or rollback scenarios