diff --git a/src/index.css b/src/index.css index 5256a93..4fbb6ad 100644 --- a/src/index.css +++ b/src/index.css @@ -2141,3 +2141,11 @@ select.studio-input { background: var(--bp-paper); } .agent-llm-off { color: var(--bp-muted); } .agent-llm-unknown { color: var(--bp-muted); } .agent-llm-hint { font-size: 11px; color: var(--bp-muted); line-height: 1.4; } + +.approvals-actions-toggle { + display: inline-flex; align-items: center; gap: 6px; + margin-left: 10px; + font-family: var(--bp-mono); font-size: 11px; + color: var(--bp-navy); cursor: pointer; +} +.approvals-actions-toggle input { cursor: pointer; } diff --git a/src/scenes/Agent.tsx b/src/scenes/Agent.tsx index af36bcd..f5daf26 100644 --- a/src/scenes/Agent.tsx +++ b/src/scenes/Agent.tsx @@ -81,7 +81,7 @@ export default function Agent() {

Deterministic command router with EA2-backed text memory.

LLM provider · {llmState === "ready" ? "ON" : llmState === "off" ? "OFF" : "…"} - {llmState === "off" && Set OPENAI_API_KEY or ANTHROPIC_API_KEY to enable natural language replies.} + {llmState === "off" && Natural language replies are not enabled in this environment.}
diff --git a/src/scenes/Approvals.tsx b/src/scenes/Approvals.tsx index 3c2dd2f..619201b 100644 --- a/src/scenes/Approvals.tsx +++ b/src/scenes/Approvals.tsx @@ -53,7 +53,7 @@ export default function Approvals() { const [busy, setBusy] = useState(null); const tenantId = useApp((s) => s.tenantId); - const [runtimeHealth, setRuntimeHealth] = useState<"unknown" | "up" | "down">("unknown"); + const [actionsEnabled, setActionsEnabled] = useState(false); const loadQueue = async () => { if (!tenantId) { @@ -71,21 +71,6 @@ export default function Approvals() { useEffect(() => { void loadQueue(); }, [tenantId]); - useEffect(() => { - let cancelled = false; - fetch(`${api.config.baseUrl}/api/ea2/runtime-values`, { - method: "GET", - headers: { Authorization: `Bearer ${sessionStorage.getItem("fm.mc.token.v1")}` }, - }) - .then((r) => { - if (cancelled) return; - if (r.status === 422 || r.ok) setRuntimeHealth("up"); - else setRuntimeHealth("down"); - }) - .catch(() => { if (!cancelled) setRuntimeHealth("down"); }); - return () => { cancelled = true; }; - }, []); - useEffect(() => { if (!activeKey) return; let cancelled = false; @@ -114,8 +99,8 @@ export default function Approvals() { } catch (err: any) { const msg = err.message || ""; if (/runtime-values|action_execution_failed|500/i.test(msg)) { - setRuntimeHealth("down"); - pushToast("err", "The runtime engine couldn't accept that decision. Action buttons are now disabled until it recovers."); + setActionsEnabled(false); + pushToast("err", "The runtime engine couldn't accept that decision. Live actions have been turned back off."); } else { pushToast("err", "Something went wrong handling that action. Try again in a moment."); } @@ -198,21 +183,29 @@ export default function Approvals() {
)} - {runtimeHealth === "down" && ( -
- Runtime engine is unreachable from this environment. Action buttons are disabled. Use this view to inspect cases; once the runtime comes back, actions will write to EA2. -
- )} +
+ {actionsEnabled + ? "Live actions enabled. Clicking a button below writes the decision to EA2." + : "Read-only view. Inspect cases here; enable live actions to submit decisions to EA2."} + +
{(tx.available_actions || []).map((a: any) => { - const disabled = !a.enabled || busy === a.id || runtimeHealth === "down"; + const disabled = !a.enabled || busy === a.id || !actionsEnabled; return (