Add configurable action confirmation timeout in Director Chat settings

This commit is contained in:
vegu-ai-tools
2026-04-05 02:28:26 +03:00
parent cd8b792c1c
commit 283638c193
6 changed files with 24 additions and 7 deletions

View File

@@ -36,3 +36,4 @@
- "Context Formatting: The |condensed template filter no longer permanently compacts multi-line context (e.g., world info, memories, pins) into a single line when sending prompts to the LLM. Formatting is now only compacted temporarily for deduplication comparison and restored to its original multi-line structure afterwards."
- "Client Config UX: Moved advanced settings (Inference Presets, Structured Data Format, Section Format, Response Length Enforcement, Prompt Caching, Rate Limit) into a dedicated Advanced tab to declutter the general view. A convenient link in the general tab provides quick access. Toggling Simple View on now resets to the General tab, and switching clients always starts on General."
- "Prompts Tab Alert: The top-level Prompts tab now shows a warning icon when any active template overrides are outdated, so you can spot them without opening the tab."
- "Action Confirm Timeout: The director chat action confirmation timeout is now configurable (060 minutes, default 3). Set to 0 to wait indefinitely. Found in the Director Chat settings under Action Confirmation."

View File

@@ -105,6 +105,15 @@ class DirectorChatMixin:
min=0.05,
max=0.95,
),
"action_confirm_timeout": AgentActionConfig(
type="number",
label="Action confirm timeout",
description="How long to wait (in minutes) for user confirmation of write actions. 0 means wait indefinitely.",
value=3,
step=1,
min=0,
max=60,
),
"custom_instructions": AgentActionConfig(
type="blob",
label="Custom instructions",
@@ -157,6 +166,11 @@ class DirectorChatMixin:
def chat_custom_instructions(self) -> str:
return self.actions["chat"].config["custom_instructions"].value
@property
def chat_action_confirm_timeout(self) -> int:
"""Timeout in seconds. 0 means wait indefinitely."""
return int(self.actions["chat"].config["action_confirm_timeout"].value) * 60
# === Node initialization ===
@classmethod

View File

@@ -325,7 +325,8 @@ class DirectorChatActionConfirm(Node):
async def run(self, state: GraphState):
state_value = self.get_input_value("state")
max_wait_time: int = 180
director = get_agent("director")
max_wait_time: int = director.chat_action_confirm_timeout
key: str = f"_director_chat_action_confirm_{self.id}"
name: str = self.normalized_input_value("name")
description: str = self.normalized_input_value("description")
@@ -364,7 +365,7 @@ class DirectorChatActionConfirm(Node):
node=self.id,
)
await asyncio.sleep(1)
if time.time() - start_time > max_wait_time:
if max_wait_time and time.time() - start_time > max_wait_time:
log.error(
"Director Chat Action Confirm: Max wait time reached",
node=self.id,

View File

@@ -58,7 +58,7 @@ export default {
},
},
mounted() {
if (!this.decision) {
if (!this.decision && this.timer > 0) {
this.startCountdown();
}
},

View File

@@ -14,6 +14,7 @@
:name="m.name"
:description="m.description"
:decision="m.decision"
:timer="m.timer"
:confirming="confirming[m.id]"
@decide="onDecide"
/>

View File

@@ -146,18 +146,18 @@ export default {
if(!params || !params.chat_id) return;
this.deleteChat();
},
addOrUpdateConfirmRequest(id, name, description) {
addOrUpdateConfirmRequest(id, name, description, timer) {
try {
// If there's already a pending entry for this id, just update its details
const pendingIdx = this.chatMessages.findIndex((m) => m.type === 'confirm_request' && m.id === id && !m.decision);
if (pendingIdx !== -1) {
const existing = this.chatMessages[pendingIdx];
const updated = { ...existing, name: name ?? existing.name, description: description ?? existing.description };
const updated = { ...existing, name: name ?? existing.name, description: description ?? existing.description, timer: timer ?? existing.timer };
this.chatMessages.splice(pendingIdx, 1, updated);
return;
}
// If previous entries exist but are already decided, push a new one
this.chatMessages.push({ source: 'director', type: 'confirm_request', id, name, description, decision: null });
this.chatMessages.push({ source: 'director', type: 'confirm_request', id, name, description, timer, decision: null });
} catch (e) { /* safely ignore malformed confirm requests */ }
},
markConfirmRequestDecision(id, decision) {
@@ -348,7 +348,7 @@ export default {
console.log('request_action_confirmation', data);
// Remove any trailing thinking placeholder while waiting for user decision
this.removeTrailingPlaceholder();
this.addOrUpdateConfirmRequest(data.id, data.name, data.description);
this.addOrUpdateConfirmRequest(data.id, data.name, data.description, data.timer);
return;
}