Skip to content

Commit 0458999

Browse files
Ambient Code Botclaude
andcommitted
refactor: simplify permission request code after review
- Remove hasResult alias, use hasToolResult directly - Collapse config/resolvedConfig/activeConfig triple to single lookup - Remove redundant hasattr/isinstance guards on ToolCallEndEvent - Use getattr for placeholder ID checks - Clear _permission_worker in bridge finally block (prevent GC leak) - Remove dead description initializer - Add PermissionRequest to use-agent-status.ts waiting_input detection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent bfcd54e commit 0458999

5 files changed

Lines changed: 18 additions & 18 deletions

File tree

components/frontend/src/components/session/ask-user-question.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ function parseQuestions(input: Record<string, unknown>): AskUserQuestionItem[] {
4242
return [];
4343
}
4444

45-
const hasResult = hasToolResult;
46-
4745
export const AskUserQuestionMessage: React.FC<AskUserQuestionMessageProps> = ({
4846
toolUseBlock,
4947
resultBlock,
@@ -52,7 +50,7 @@ export const AskUserQuestionMessage: React.FC<AskUserQuestionMessageProps> = ({
5250
isNewest = false,
5351
}) => {
5452
const questions = parseQuestions(toolUseBlock.input);
55-
const alreadyAnswered = hasResult(resultBlock);
53+
const alreadyAnswered = hasToolResult(resultBlock);
5654
const formattedTime = formatTimestamp(timestamp);
5755
const isMultiQuestion = questions.length > 1;
5856

components/frontend/src/components/session/permission-request.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,7 @@ export const PermissionRequestMessage: React.FC<
9292
}
9393
};
9494

95-
const config = STATUS_CONFIG[disabled && status !== "pending" ? status : "pending"];
96-
const resolvedConfig = STATUS_CONFIG[status];
97-
const activeConfig = disabled ? resolvedConfig : config;
95+
const activeConfig = STATUS_CONFIG[disabled && status !== "pending" ? status : "pending"];
9896
const Icon = activeConfig.icon;
9997

10098
return (

components/frontend/src/hooks/use-agent-status.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ import type {
55
} from "@/types/agentic-session";
66
import type { PlatformMessage } from "@/types/agui";
77

8-
function isAskUserQuestionTool(name: string): boolean {
9-
const normalized = name.toLowerCase().replace(/[^a-z]/g, "");
10-
return normalized === "askuserquestion";
8+
function normalizeToolName(name: string): string {
9+
return name.toLowerCase().replace(/[^a-z]/g, "");
10+
}
11+
12+
function isHumanInTheLoopTool(name: string): boolean {
13+
const normalized = normalizeToolName(name);
14+
return normalized === "askuserquestion" || normalized === "permissionrequest";
1115
}
1216

1317
/**
@@ -38,7 +42,7 @@ export function useAgentStatus(
3842

3943
// Check the last tool call on this message
4044
const lastTc = msg.toolCalls[msg.toolCalls.length - 1];
41-
if (lastTc.function?.name && isAskUserQuestionTool(lastTc.function.name)) {
45+
if (lastTc.function?.name && isHumanInTheLoopTool(lastTc.function.name)) {
4246
const hasResult =
4347
lastTc.result !== undefined &&
4448
lastTc.result !== null &&

components/runners/ambient-runner/ag_ui_claude_sdk/adapter.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,6 @@ async def _can_use_tool(
317317
# Build a human-readable description of what Claude wants to do.
318318
file_path = input_data.get("file_path", "")
319319
command = input_data.get("command", "")
320-
description = ""
321320
if file_path:
322321
description = f"{tool_name} on {file_path}"
323322
elif command:
@@ -964,20 +963,18 @@ def flush_pending_msg():
964963
if isinstance(message, BaseEvent):
965964
# Rewrite placeholder thread/run IDs injected by
966965
# can_use_tool (which doesn't know the real IDs).
967-
if hasattr(message, "thread_id") and message.thread_id == _PERM_PLACEHOLDER_ID:
966+
if getattr(message, "thread_id", None) == _PERM_PLACEHOLDER_ID:
968967
message.thread_id = thread_id
969-
if hasattr(message, "run_id") and message.run_id == _PERM_PLACEHOLDER_ID:
968+
if getattr(message, "run_id", None) == _PERM_PLACEHOLDER_ID:
970969
message.run_id = run_id
971970

972971
yield message
973972

974-
# Detect PermissionRequest halt: the ToolCallEndEvent
975-
# for a PermissionRequest tool signals that we should
976-
# halt just like a frontend tool.
973+
# PermissionRequest halt: ToolCallEndEvent with a
974+
# perm- prefixed ID triggers the same halt as a
975+
# frontend tool.
977976
if (
978977
isinstance(message, ToolCallEndEvent)
979-
and hasattr(message, "tool_call_id")
980-
and isinstance(message.tool_call_id, str)
981978
and message.tool_call_id.startswith(_PERM_TOOL_ID_PREFIX)
982979
):
983980
logger.debug(

components/runners/ambient-runner/ambient_runner/bridges/claude/bridge.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ async def run(
233233
# Clear the halt flag for this thread
234234
self._halted_by_thread.pop(thread_id, None)
235235
finally:
236+
# Release worker reference so destroyed workers can be GC'd.
237+
self._adapter.set_permission_worker(None)
238+
236239
# Clear caller token immediately — never persist between turns.
237240
if self._context:
238241
self._context.caller_token = ""

0 commit comments

Comments
 (0)