Skip to content

fix(thread): 🐛 hide custom agent tool calls and display proper names#204

Open
jorben wants to merge 3 commits into
masterfrom
feat/custom-subagents-ui
Open

fix(thread): 🐛 hide custom agent tool calls and display proper names#204
jorben wants to merge 3 commits into
masterfrom
feat/custom-subagents-ui

Conversation

@jorben
Copy link
Copy Markdown
Contributor

@jorben jorben commented May 25, 2026

Summary

  • Fix custom agent agent_{slug} tool calls leaking into the timeline alongside helper cards
  • Display user-defined custom agent names instead of raw helper_custom_{slug} strings
  • Unify isRuntimeOrchestrationToolName to use startsWith("agent_") pattern, eliminating duplicate implementations

Test Plan

  • npm run typecheck passes
  • npm run test:unit passes (752 tests)
  • Create a custom agent (e.g. slug=refactor, name="Refactor Agent"), trigger a call, verify timeline no longer shows a duplicate agent_refactor tool card
  • Verify the helper card displays the custom agent's user-defined name

🤖 Generated with TiyCode

Unify isRuntimeOrchestrationToolName to use startsWith("agent_") pattern
so custom agent_{slug} calls are hidden from timeline alongside built-in
agent_explore/agent_review. Add slugToNameMap support to formatHelperKind
so custom agents show user-defined names instead of raw helper_custom_{slug}.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 25, 2026

AI Code Review Summary

PR: #204 (fix(thread): 🐛 hide custom agent tool calls and display proper names)
Preferred language: English

Overall Assessment

Detected 3 actionable findings, prioritize CRITICAL/HIGH before merge.

Major Findings by Severity

  • MEDIUM (1)
    • src/shared/constants/tool-names.ts:33 - Prefix-based identification of privileged orchestration tools
  • LOW (2)
    • src/modules/workbench-shell/ui/runtime-thread-surface-helpers.ts:118 - Fallback handling for empty slug in custom helper kind
    • src/shared/constants/tool-names.ts:32 - Namespace Collision Risk with Prefix-Based Tool Classification

Actionable Suggestions

  • Buddy, consider fallback checks like return customName ?? (slug ? capitalizeSlug(slug) : 'Custom Agent'); on line 121 in runtime-thread-surface-helpers.ts to guarantee a visible fallback name.
  • Buddy, consider adding a registration check/validation that blocks standard (non-orchestration) custom tools from using the reserved 'agent_' prefix.
  • Verify where isRuntimeOrchestrationToolName is called in both the frontend and backend. Ensure it is not used as a security/consent-bypass check for third-party or custom user tools.
  • Implement a robust, strictly controlled registry for orchestration-level tools rather than relying on string prefixes.

Potential Risks

  • Empty rendering labels on custom subagent elements if a malformed prefix without a slug is received.
  • Third-party or user-configured tools that happen to use the 'agent_' prefix will be treated as runtime orchestration tools, which may cause execution routing failures.
  • Malicious extensions or custom tools bypassing security boundaries or confirmation dialogs if those boundaries rely on the isRuntimeOrchestrationTool classification.

Test Suggestions

  • Run npm run test:unit to verify the vitest suite handles custom helper formatting behaviors.
  • Ensure that backend integration tests verify how the agent session runner handles unknown tools prefixed with 'agent_' to confirm failure modes are graceful.
  • Add integration tests in the Tauri/Rust core runtime backend to ensure tool name spoofing (e.g. prefixing with 'agent_') cannot bypass security, capability checks, or prompt consent checks.

File-Level Coverage Notes

  • src/modules/workbench-shell/ui/runtime-thread-surface-helpers.ts: The changes successfully add support for custom subagent helpers by introducing custom slug-to-name mapping and automated fallback capitalization. (Overall robust functional code.)
  • src/modules/workbench-shell/ui/runtime-thread-surface-helpers.test.ts: Excellent testing suite that achieves robust coverage of standard cases, unknown helpers, dynamic map fallbacks, and edge cases. (Great use of a mock helper generator function.)
  • src/modules/workbench-shell/ui/runtime-thread-surface-state.ts: A clean refactoring to centralize orchestration tool identifier matching into the shared constants folder. (Enhances code consistency and maintainability.)
  • src/modules/workbench-shell/ui/runtime-thread-surface.tsx: Efficient mapping of custom subagent slugs using React useMemo to prevent unnecessary re-computations during render loop iterations. (Correctly integrates the new slugToNameMap argument across helper formatting calls.)
  • src/shared/constants/tool-names.ts: Refactoring tool verification from an allowlist to a prefix-based match introduces a potential security risk of authorization bypass if orchestration tools possess elevated capabilities. (Buddy, we should ensure the backend enforcement does not solely rely on this frontend helper for determining tool security boundaries.)
  • src/shared/constants/tool-names.test.ts: The test changes align with the implementation change but confirm that arbitrary extensions (e.g., 'agent_refactor') are now classified as orchestration tools. (The tests verify the prefix matching behavior but remove previous negative test cases for extended matches, validating that prefix matching is indeed the new intended behavior.)

Inline Downgraded Items (processed but not inline)

  • None

Coverage Status

  • Target files: 6
  • Covered files: 6
  • Uncovered files: 0
  • No-patch/binary covered as file-level: 0
  • Findings with unknown confidence (N/A): 0

Uncovered list:

  • None

No-patch covered list:

  • None

Runtime/Budget

  • Rounds used: 1/4
  • Planned batches: 2
  • Executed batches: 2
  • Sub-agent runs: 3
  • Planner calls: 1
  • Reviewer calls: 4
  • Model calls: 5/64
  • Structured-output summary-only degradation: NO

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated PR review completed.

  • Findings kept: 4
  • Findings with unknown confidence: 0
  • Inline comments attempted: 4
  • Target files: 5
  • Covered files: 5
  • Uncovered files: 0
    See the summary comment for detailed analysis and coverage details.

.join(" ");
}

export function formatHelperKind(

This comment was marked as outdated.

const agentProfiles = useStore(settingsStore, (s) => s.agentProfiles);
const customSubagents = useStore(settingsStore, (s) => s.customSubagents, shallowEqual);
const customAgentSlugToName = useMemo(
() => new Map(customSubagents.map((a) => [a.slug, a.name])),

This comment was marked as outdated.

Comment thread src/shared/constants/tool-names.ts Outdated

export function isRuntimeOrchestrationToolName(toolName: string): boolean {
return (RUNTIME_ORCHESTRATION_TOOLS as ReadonlyArray<string>).includes(toolName);
return toolName.startsWith(RUNTIME_ORCHESTRATION_TOOL_PREFIX);

This comment was marked as outdated.

Comment thread src/shared/constants/tool-names.ts Outdated

export function isRuntimeOrchestrationToolName(toolName: string): boolean {
return (RUNTIME_ORCHESTRATION_TOOLS as ReadonlyArray<string>).includes(toolName);
return toolName.startsWith(RUNTIME_ORCHESTRATION_TOOL_PREFIX);

This comment was marked as outdated.

…tests

Require at least one character after the agent_ prefix so bare "agent_"
is no longer classified as a runtime orchestration tool. Add unit tests
for formatHelperKind, formatHelperName, formatHelperSummary covering
built-in kinds, custom agent name lookup, slug fallback capitalization,
and edge cases.
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated PR review completed.

  • Findings kept: 2
  • Findings with unknown confidence: 0
  • Inline comments attempted: 2
  • Target files: 6
  • Covered files: 6
  • Uncovered files: 0
    See the summary comment for detailed analysis and coverage details.

@@ -26,7 +29,10 @@ export const DEFAULT_COLLAPSED_TOOLS = [
] as const;

export function isRuntimeOrchestrationToolName(toolName: string): boolean {

This comment was marked as outdated.

export function formatHelperKind(kind: string) {
const CUSTOM_PREFIX = "helper_custom_";

function capitalizeSlug(slug: string) {

This comment was marked as outdated.

Add .filter(Boolean) after split("-") so that hypothetical consecutive
hyphens or trailing hyphens do not produce stray empty-string segments.
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated PR review completed.

  • Findings kept: 3
  • Findings with unknown confidence: 0
  • Inline comments attempted: 3
  • Target files: 6
  • Covered files: 6
  • Uncovered files: 0
    See the summary comment for detailed analysis and coverage details.

export function isRuntimeOrchestrationToolName(toolName: string): boolean {
return (RUNTIME_ORCHESTRATION_TOOLS as ReadonlyArray<string>).includes(toolName);
return (
toolName.startsWith(RUNTIME_ORCHESTRATION_TOOL_PREFIX)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Prefix-based identification of privileged orchestration tools

Buddy, the function isRuntimeOrchestrationToolName has been changed from checking an explicit allowlist to checking a simple prefix ('agent_'). If runtime orchestration tools receive elevated privileges, bypass consent prompts, or run in a different isolation boundary, any untrusted custom tool or plugin could gain these privileges simply by prefixing its name with 'agent_'.

Suggestion: Instead of relying on a string prefix to identify privileged orchestration tools, maintain a strict and secure registry of authorized orchestration tools, or require explicit registration with verification rather than basic prefix matching.

Risk: Untrusted or malicious extensions/tools can masquerade as orchestration tools, potentially escalating privileges, bypassing validation, or execution policies.

Confidence: 0.85

[From SubAgent: security]

case "helper_review":
return "Review Agent";
default:
if (kind.startsWith(CUSTOM_PREFIX)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW] Fallback handling for empty slug in custom helper kind

If the helper kind is exactly 'helper_custom_' (with an empty slug), capitalizeSlug returns an empty string, which causes formatHelperKind to return an empty string. This could result in blank names rendering in the UI.

Suggestion: Add a defensive fallback in formatHelperKind to return a default string like 'Custom Agent' or the raw 'kind' string if the sliced slug is falsy.

Risk: Minor visual glitch (empty label) in the UI if an empty custom helper kind ever reaches the client.

Confidence: 0.90

[From SubAgent: general]


export function isRuntimeOrchestrationToolName(toolName: string): boolean {
return (RUNTIME_ORCHESTRATION_TOOLS as ReadonlyArray<string>).includes(toolName);
return (
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW] Namespace Collision Risk with Prefix-Based Tool Classification

Switching from an explicit allowlist to a prefix-based check ('agent_') means any tool (including user-defined or third-party extensions) that happens to begin with 'agent_' will be treated as a runtime orchestration tool. This could lead to runtime errors or security/routing misbehaviors if standard tools are mistakenly processed as orchestration tools.

Suggestion: Buddy, make sure there is documentation or validation at the tool registration layer that reserves the 'agent_' prefix exclusively for runtime orchestration tools, or enforce this via system-level validation.

Risk: Custom tools from extensions or integrations prefixed with 'agent_' might be mistakenly routed as runtime orchestration tools, leading to unexpected behavior or execution failures.

Confidence: 0.90

[From SubAgent: general]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant