CallMeDaniel Claude Opus 4.6 (1M context) commited on
Commit
0b9dfdd
·
1 Parent(s): e74a008

feat: add confirm/revise buttons to agent recommendations

Browse files

Agent messages now show CONFIRM and REVISE buttons. Confirming sends the
recommendation as a decision that updates the design state. Revising
pre-fills the input with context for the user to edit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Files changed (2) hide show
  1. agents/design_state.py +6 -0
  2. web/index.html +91 -1
agents/design_state.py CHANGED
@@ -168,6 +168,12 @@ class DesignState(BaseModel):
168
  if s not in state.decisions and len(state.decisions) < max_decisions:
169
  state.decisions.append(s)
170
 
 
 
 
 
 
 
171
  # Extract part name from user message if not set
172
  if not state.part_name and user_message:
173
  name_patterns = [
 
168
  if s not in state.decisions and len(state.decisions) < max_decisions:
169
  state.decisions.append(s)
170
 
171
+ # Extract confirmed decisions from user messages ("Confirmed: Agent: ...")
172
+ if user_message.lower().startswith("confirmed:"):
173
+ decision = user_message.split(":", 2)[-1].strip()
174
+ if decision and decision not in state.decisions and len(state.decisions) < max_decisions:
175
+ state.decisions.append(decision)
176
+
177
  # Extract part name from user message if not set
178
  if not state.part_name and user_message:
179
  name_patterns = [
web/index.html CHANGED
@@ -694,6 +694,54 @@
694
 
695
  .msg-view-code:hover { opacity: 0.7; }
696
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
697
  /* Typing indicator */
698
  .typing-indicator {
699
  display: flex;
@@ -1626,6 +1674,7 @@ function addMessage(msg) {
1626
  const isCad = agentId === 'cad';
1627
 
1628
  el.className = 'msg msg-agent';
 
1629
 
1630
  let html = '<div class="msg-avatar" style="background: ' + color + ';">' + avatar + '</div>';
1631
  html += '<div class="msg-agent-body">';
@@ -1637,14 +1686,55 @@ function addMessage(msg) {
1637
  html += '<br><a class="msg-view-code" onclick="openCodeModal()">&#9654; View code</a>';
1638
  }
1639
 
1640
- html += '</div></div>';
 
 
 
 
 
 
 
 
 
 
 
 
1641
  el.innerHTML = html;
 
 
1642
  }
1643
 
1644
  container.appendChild(el);
1645
  scrollChatToBottom();
1646
  }
1647
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1648
  function showTyping() {
1649
  const container = document.getElementById('chat-messages');
1650
  const el = document.createElement('div');
 
694
 
695
  .msg-view-code:hover { opacity: 0.7; }
696
 
697
+ .msg-actions {
698
+ display: flex;
699
+ gap: 6px;
700
+ margin-top: 8px;
701
+ }
702
+
703
+ .msg-actions.resolved { display: none; }
704
+
705
+ .msg-action-btn {
706
+ all: unset;
707
+ font-family: var(--font-mono);
708
+ font-size: 10px;
709
+ font-weight: 600;
710
+ letter-spacing: 0.5px;
711
+ padding: 4px 12px;
712
+ border-radius: 3px;
713
+ cursor: pointer;
714
+ transition: all 0.15s;
715
+ }
716
+
717
+ .msg-action-btn.confirm {
718
+ background: rgba(0, 230, 118, 0.1);
719
+ border: 1px solid rgba(0, 230, 118, 0.3);
720
+ color: var(--success);
721
+ }
722
+
723
+ .msg-action-btn.confirm:hover {
724
+ background: rgba(0, 230, 118, 0.2);
725
+ }
726
+
727
+ .msg-action-btn.revise {
728
+ background: rgba(255, 171, 64, 0.08);
729
+ border: 1px solid rgba(255, 171, 64, 0.25);
730
+ color: var(--warning);
731
+ }
732
+
733
+ .msg-action-btn.revise:hover {
734
+ background: rgba(255, 171, 64, 0.15);
735
+ }
736
+
737
+ .msg-confirmed {
738
+ font-family: var(--font-mono);
739
+ font-size: 10px;
740
+ color: var(--success);
741
+ margin-top: 6px;
742
+ letter-spacing: 0.5px;
743
+ }
744
+
745
  /* Typing indicator */
746
  .typing-indicator {
747
  display: flex;
 
1674
  const isCad = agentId === 'cad';
1675
 
1676
  el.className = 'msg msg-agent';
1677
+ const msgId = 'msg-' + Date.now() + '-' + Math.random().toString(36).slice(2, 6);
1678
 
1679
  let html = '<div class="msg-avatar" style="background: ' + color + ';">' + avatar + '</div>';
1680
  html += '<div class="msg-agent-body">';
 
1686
  html += '<br><a class="msg-view-code" onclick="openCodeModal()">&#9654; View code</a>';
1687
  }
1688
 
1689
+ html += '</div>';
1690
+
1691
+ // Add confirm/revise buttons for agent recommendations (not system, not code-only)
1692
+ const isSystem = agentId === 'system';
1693
+ const isCodeOnly = isCad && msg.code;
1694
+ if (!isSystem && !isCodeOnly && msg.content && !msg.content.startsWith('NOT READY:')) {
1695
+ html += '<div class="msg-actions" id="' + msgId + '-actions">';
1696
+ html += '<button class="msg-action-btn confirm" onclick="confirmRecommendation(\'' + msgId + '\', \'' + escapeHtml(agentId) + '\')">CONFIRM</button>';
1697
+ html += '<button class="msg-action-btn revise" onclick="reviseRecommendation(\'' + msgId + '\', \'' + escapeHtml(agentId) + '\')">REVISE</button>';
1698
+ html += '</div>';
1699
+ }
1700
+
1701
+ html += '</div>';
1702
  el.innerHTML = html;
1703
+ el.dataset.msgId = msgId;
1704
+ el.dataset.content = msg.content;
1705
  }
1706
 
1707
  container.appendChild(el);
1708
  scrollChatToBottom();
1709
  }
1710
 
1711
+ function confirmRecommendation(msgId, agentId) {
1712
+ const el = document.querySelector('[data-msg-id="' + msgId + '"]');
1713
+ if (!el) return;
1714
+ const content = el.dataset.content;
1715
+ const actions = document.getElementById(msgId + '-actions');
1716
+ if (actions) {
1717
+ actions.innerHTML = '<div class="msg-confirmed">CONFIRMED</div>';
1718
+ }
1719
+ // Send confirmation as user message so it updates design state
1720
+ const agentName = (AGENTS[agentId] || {}).name || agentId;
1721
+ sendMessage('Confirmed: ' + agentName + ': ' + content);
1722
+ }
1723
+
1724
+ function reviseRecommendation(msgId, agentId) {
1725
+ const el = document.querySelector('[data-msg-id="' + msgId + '"]');
1726
+ if (!el) return;
1727
+ const content = el.dataset.content;
1728
+ const actions = document.getElementById(msgId + '-actions');
1729
+ if (actions) actions.classList.add('resolved');
1730
+ // Pre-fill input with context for the user to edit
1731
+ const input = document.getElementById('chat-input');
1732
+ const agentName = (AGENTS[agentId] || {}).name || agentId;
1733
+ input.value = 'Regarding ' + agentName + '\'s suggestion: ';
1734
+ input.focus();
1735
+ input.setSelectionRange(input.value.length, input.value.length);
1736
+ }
1737
+
1738
  function showTyping() {
1739
  const container = document.getElementById('chat-messages');
1740
  const el = document.createElement('div');