mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
## Summary
- Integrates existing Human-In-The-Loop (HITL) review infrastructure
into CoPilot's direct block execution (`run_block`) for blocks marked
with `is_sensitive_action=True`
- Removes the `PendingHumanReview → AgentGraphExecution` FK constraint
to support synthetic CoPilot session IDs (migration included)
- Adds `ReviewRequiredResponse` model + frontend `ReviewRequiredCard`
component to surface review status in the chat UI
- Auto-approval works within a CoPilot session: once a block is
approved, subsequent executions of the same block in the same session
are auto-approved (using `copilot-session-{session_id}` as
`graph_exec_id` and `copilot-node-{block_id}` as `node_id`)
## Test plan
- [x] All 11 `run_block_test.py` tests pass (3 new sensitive action
tests)
- [ ] Manual: Execute a block with `is_sensitive_action=True` in CoPilot
→ verify ReviewRequiredResponse is returned and rendered
- [ ] Manual: Approve in review panel → re-execute the same block →
verify auto-approval kicks in
- [ ] Manual: Verify non-sensitive blocks still execute without review
38 lines
1.6 KiB
Python
38 lines
1.6 KiB
Python
"""Shared constants for the CoPilot module."""
|
|
|
|
# Special message prefixes for text-based markers (parsed by frontend).
|
|
# The hex suffix makes accidental LLM generation of these strings virtually
|
|
# impossible, avoiding false-positive marker detection in normal conversation.
|
|
COPILOT_ERROR_PREFIX = "[__COPILOT_ERROR_f7a1__]" # Renders as ErrorCard
|
|
COPILOT_SYSTEM_PREFIX = "[__COPILOT_SYSTEM_e3b0__]" # Renders as system info message
|
|
|
|
# Prefix for all synthetic IDs generated by CoPilot block execution.
|
|
# Used to distinguish CoPilot-generated records from real graph execution records
|
|
# in PendingHumanReview and other tables.
|
|
COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"
|
|
|
|
# Sub-prefixes for session-scoped and node-scoped synthetic IDs.
|
|
COPILOT_SESSION_PREFIX = f"{COPILOT_SYNTHETIC_ID_PREFIX}session-"
|
|
COPILOT_NODE_PREFIX = f"{COPILOT_SYNTHETIC_ID_PREFIX}node-"
|
|
|
|
# Separator used in synthetic node_exec_id to encode node_id.
|
|
# Format: "{node_id}:{random_hex}" — extract node_id via rsplit(":", 1)[0]
|
|
COPILOT_NODE_EXEC_ID_SEPARATOR = ":"
|
|
|
|
# Compaction notice messages shown to users.
|
|
COMPACTION_DONE_MSG = "Earlier messages were summarized to fit within context limits."
|
|
COMPACTION_TOOL_NAME = "context_compaction"
|
|
|
|
|
|
def is_copilot_synthetic_id(id_value: str) -> bool:
|
|
"""Check if an ID is a CoPilot synthetic ID (not from a real graph execution)."""
|
|
return id_value.startswith(COPILOT_SYNTHETIC_ID_PREFIX)
|
|
|
|
|
|
def parse_node_id_from_exec_id(node_exec_id: str) -> str:
|
|
"""Extract node_id from a synthetic node_exec_id.
|
|
|
|
Format: "{node_id}:{random_hex}" → returns "{node_id}".
|
|
"""
|
|
return node_exec_id.rsplit(COPILOT_NODE_EXEC_ID_SEPARATOR, 1)[0]
|