Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -218,11 +218,11 @@ def step_game(human_final_order: int, human_initial_order: int, ai_suggestion: i
|
|
| 218 |
total_backlog_before_shipping[name] = echelons[name]['backlog'] + incoming_order_for_this_week
|
| 219 |
decision_point_states = {}
|
| 220 |
for name in echelon_order:
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
current_week_orders = {}
|
| 227 |
for name in echelon_order:
|
| 228 |
e = echelons[name]; prompt_state = decision_point_states[name]
|
|
@@ -433,7 +433,7 @@ else:
|
|
| 433 |
|
| 434 |
c1, c2 = st.columns(2)
|
| 435 |
with c1:
|
| 436 |
-
|
| 437 |
with c2:
|
| 438 |
info_sharing = st.selectbox("Information Sharing Level", ('local', 'full'), format_func=lambda x: x.title(), help="**Local:** You and the AI agents can only see your own inventory and incoming orders. **Full:** Everyone can see the entire supply chain's status and the true end-customer demand.")
|
| 439 |
|
|
@@ -456,7 +456,7 @@ else:
|
|
| 456 |
else:
|
| 457 |
# 新ID,直接开始
|
| 458 |
if 'last_id_warning' in st.session_state:
|
| 459 |
-
|
| 460 |
init_game_state(llm_personality, info_sharing, participant_id)
|
| 461 |
st.rerun()
|
| 462 |
# ===========================================================
|
|
@@ -504,32 +504,43 @@ else:
|
|
| 504 |
if downstream_name:
|
| 505 |
current_incoming_order = state['last_week_orders'].get(downstream_name, 0)
|
| 506 |
st.write(f"Incoming Order (This Week): **{current_incoming_order}**")
|
| 507 |
-
|
| 508 |
if name == "Factory":
|
| 509 |
arriving_this_week = list(state['factory_production_pipeline'])[0] if state['factory_production_pipeline'] else 0
|
| 510 |
st.write(f"Completing This Week: **{arriving_this_week}**")
|
| 511 |
-
|
|
|
|
|
|
|
|
|
|
| 512 |
st.write(f"Completing Next Week: **{prod_completing_next}**")
|
| 513 |
else:
|
| 514 |
arriving_this_week = list(e['incoming_shipments'])[0] if e['incoming_shipments'] else 0
|
| 515 |
st.write(f"Arriving This Week: **{arriving_this_week}**")
|
| 516 |
|
| 517 |
arriving_next = 0
|
| 518 |
-
|
| 519 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 520 |
arriving_next = list(e['incoming_shipments'])[1]
|
| 521 |
-
|
|
|
|
| 522 |
elif name in ('Wholesaler', 'Retailer') and e['incoming_shipments'].maxlen == 2:
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
|
| 534 |
st.write(f"Arriving Next Week: **{arriving_next}**")
|
| 535 |
|
|
@@ -547,7 +558,7 @@ else:
|
|
| 547 |
current_incoming_order = 0
|
| 548 |
downstream_name = e['downstream_name'] # Wholesaler
|
| 549 |
if downstream_name:
|
| 550 |
-
|
| 551 |
st.write(f"**Incoming Order (This Week):**\n# {current_incoming_order}")
|
| 552 |
|
| 553 |
with col3:
|
|
@@ -570,9 +581,9 @@ else:
|
|
| 570 |
e_curr = echelons[name] # This is END OF LAST WEEK state
|
| 571 |
arrived = 0
|
| 572 |
if name == "Factory":
|
| 573 |
-
|
| 574 |
else:
|
| 575 |
-
|
| 576 |
|
| 577 |
inc_order_this_week = 0
|
| 578 |
if name == "Retailer": inc_order_this_week = get_customer_demand(week)
|
|
@@ -622,7 +633,7 @@ else:
|
|
| 622 |
if st.form_submit_button("Submit Final Order & Advance to Next Week"):
|
| 623 |
final_order_value = st.session_state.get('final_order_input', 0)
|
| 624 |
final_order_value = int(final_order_value) if final_order_value is not None else 0
|
| 625 |
-
|
| 626 |
step_game(final_order_value, state['human_initial_order'], ai_suggestion)
|
| 627 |
|
| 628 |
if 'final_order_input' in st.session_state: del st.session_state.final_order_input
|
|
@@ -647,11 +658,11 @@ else:
|
|
| 647 |
f'{human_role}.arrived_this_week', f'{human_role}.incoming_order',
|
| 648 |
f'{human_role}.initial_order', f'{human_role}.ai_suggestion', f'{human_role}.order_placed',
|
| 649 |
f'{human_role}.arriving_next_week', f'{human_role}.weekly_cost'
|
| 650 |
-
|
| 651 |
final_cols_to_display = [col for col in ordered_display_cols_keys if col in history_df.columns]
|
| 652 |
|
| 653 |
if not final_cols_to_display:
|
| 654 |
-
|
| 655 |
else:
|
| 656 |
display_df = history_df[final_cols_to_display].rename(columns=human_cols)
|
| 657 |
if 'Weekly Cost' in display_df.columns:
|
|
|
|
| 218 |
total_backlog_before_shipping[name] = echelons[name]['backlog'] + incoming_order_for_this_week
|
| 219 |
decision_point_states = {}
|
| 220 |
for name in echelon_order:
|
| 221 |
+
decision_point_states[name] = {
|
| 222 |
+
'name': name, 'inventory': inventory_after_arrival[name],
|
| 223 |
+
'backlog': total_backlog_before_shipping[name], 'incoming_order': echelons[name]['incoming_order'],
|
| 224 |
+
'incoming_shipments': echelons[name]['incoming_shipments'].copy() if name != "Factory" else deque(),
|
| 225 |
+
}
|
| 226 |
current_week_orders = {}
|
| 227 |
for name in echelon_order:
|
| 228 |
e = echelons[name]; prompt_state = decision_point_states[name]
|
|
|
|
| 433 |
|
| 434 |
c1, c2 = st.columns(2)
|
| 435 |
with c1:
|
| 436 |
+
llm_personality = st.selectbox("AI Agent 'Personality'", ('human_like', 'perfect_rational'), format_func=lambda x: x.replace('_', ' ').title(), help="**Human-like:** Tends to react emotionally, potentially over-ordering. **Perfect Rational:** Uses a mathematical heuristic to make stable, logical decisions.")
|
| 437 |
with c2:
|
| 438 |
info_sharing = st.selectbox("Information Sharing Level", ('local', 'full'), format_func=lambda x: x.title(), help="**Local:** You and the AI agents can only see your own inventory and incoming orders. **Full:** Everyone can see the entire supply chain's status and the true end-customer demand.")
|
| 439 |
|
|
|
|
| 456 |
else:
|
| 457 |
# 新ID,直接开始
|
| 458 |
if 'last_id_warning' in st.session_state:
|
| 459 |
+
del st.session_state['last_id_warning']
|
| 460 |
init_game_state(llm_personality, info_sharing, participant_id)
|
| 461 |
st.rerun()
|
| 462 |
# ===========================================================
|
|
|
|
| 504 |
if downstream_name:
|
| 505 |
current_incoming_order = state['last_week_orders'].get(downstream_name, 0)
|
| 506 |
st.write(f"Incoming Order (This Week): **{current_incoming_order}**")
|
| 507 |
+
|
| 508 |
if name == "Factory":
|
| 509 |
arriving_this_week = list(state['factory_production_pipeline'])[0] if state['factory_production_pipeline'] else 0
|
| 510 |
st.write(f"Completing This Week: **{arriving_this_week}**")
|
| 511 |
+
|
| 512 |
+
# FIX: 'Next week' for Factory is the order it just received from Distributor
|
| 513 |
+
prod_completing_next = state['last_week_orders'].get("Distributor", 0)
|
| 514 |
+
|
| 515 |
st.write(f"Completing Next Week: **{prod_completing_next}**")
|
| 516 |
else:
|
| 517 |
arriving_this_week = list(e['incoming_shipments'])[0] if e['incoming_shipments'] else 0
|
| 518 |
st.write(f"Arriving This Week: **{arriving_this_week}**")
|
| 519 |
|
| 520 |
arriving_next = 0
|
| 521 |
+
|
| 522 |
+
# FIX: Add special case for Distributor
|
| 523 |
+
if name == 'Distributor':
|
| 524 |
+
# 'Next week' for Distributor is what's in the factory pipeline
|
| 525 |
+
if state['factory_production_pipeline']:
|
| 526 |
+
arriving_next = list(state['factory_production_pipeline'])[0]
|
| 527 |
+
|
| 528 |
+
# Original logic for R/W (q_len > 1)
|
| 529 |
+
elif len(e['incoming_shipments']) > 1:
|
| 530 |
arriving_next = list(e['incoming_shipments'])[1]
|
| 531 |
+
|
| 532 |
+
# Original logic for R/W (q_len = 1 or 0)
|
| 533 |
elif name in ('Wholesaler', 'Retailer') and e['incoming_shipments'].maxlen == 2:
|
| 534 |
+
# 如果队列长度为1,说明下周的货在[0],这周的货是0
|
| 535 |
+
if len(e['incoming_shipments']) == 1:
|
| 536 |
+
arriving_next = list(e['incoming_shipments'])[0]
|
| 537 |
+
arriving_this_week = 0 # 覆盖
|
| 538 |
+
else: # 队列为0
|
| 539 |
+
arriving_next = 0
|
| 540 |
+
arriving_this_week = 0 # 覆盖
|
| 541 |
+
|
| 542 |
+
# 重新显示修正后的"Arriving This Week"
|
| 543 |
+
st.write(f"Arriving This Week: **{arriving_this_week}**")
|
| 544 |
|
| 545 |
st.write(f"Arriving Next Week: **{arriving_next}**")
|
| 546 |
|
|
|
|
| 558 |
current_incoming_order = 0
|
| 559 |
downstream_name = e['downstream_name'] # Wholesaler
|
| 560 |
if downstream_name:
|
| 561 |
+
current_incoming_order = state['last_week_orders'].get(downstream_name, 0)
|
| 562 |
st.write(f"**Incoming Order (This Week):**\n# {current_incoming_order}")
|
| 563 |
|
| 564 |
with col3:
|
|
|
|
| 581 |
e_curr = echelons[name] # This is END OF LAST WEEK state
|
| 582 |
arrived = 0
|
| 583 |
if name == "Factory":
|
| 584 |
+
if state['factory_production_pipeline']: arrived = list(state['factory_production_pipeline'])[0]
|
| 585 |
else:
|
| 586 |
+
if e_curr['incoming_shipments']: arrived = list(e_curr['incoming_shipments'])[0]
|
| 587 |
|
| 588 |
inc_order_this_week = 0
|
| 589 |
if name == "Retailer": inc_order_this_week = get_customer_demand(week)
|
|
|
|
| 633 |
if st.form_submit_button("Submit Final Order & Advance to Next Week"):
|
| 634 |
final_order_value = st.session_state.get('final_order_input', 0)
|
| 635 |
final_order_value = int(final_order_value) if final_order_value is not None else 0
|
| 636 |
+
|
| 637 |
step_game(final_order_value, state['human_initial_order'], ai_suggestion)
|
| 638 |
|
| 639 |
if 'final_order_input' in st.session_state: del st.session_state.final_order_input
|
|
|
|
| 658 |
f'{human_role}.arrived_this_week', f'{human_role}.incoming_order',
|
| 659 |
f'{human_role}.initial_order', f'{human_role}.ai_suggestion', f'{human_role}.order_placed',
|
| 660 |
f'{human_role}.arriving_next_week', f'{human_role}.weekly_cost'
|
| 661 |
+
]
|
| 662 |
final_cols_to_display = [col for col in ordered_display_cols_keys if col in history_df.columns]
|
| 663 |
|
| 664 |
if not final_cols_to_display:
|
| 665 |
+
st.write("No data columns available to display.")
|
| 666 |
else:
|
| 667 |
display_df = history_df[final_cols_to_display].rename(columns=human_cols)
|
| 668 |
if 'Weekly Cost' in display_df.columns:
|