Skip to content

fix(agents): normalize agent handoff prompt values to ensure default instructions#12707

Open
xxsLuna wants to merge 3 commits intodanny-avila:devfrom
xxsLuna:fix/agent-handoff-prompt-normalization
Open

fix(agents): normalize agent handoff prompt values to ensure default instructions#12707
xxsLuna wants to merge 3 commits intodanny-avila:devfrom
xxsLuna:fix/agent-handoff-prompt-normalization

Conversation

@xxsLuna
Copy link
Copy Markdown

@xxsLuna xxsLuna commented Apr 17, 2026

Summary

This PR fixes a bug where clearing handoff configuration fields in the UI would send empty strings ("") to the backend, preventing default values (like 'instructions') from being applied.

Changes

  • Backend: Added .transform() to graphEdgeSchema in packages/api/src/agents/validation.ts to convert empty strings to undefined.
  • Frontend: Updated AgentHandoffs.tsx components to normalize empty inputs to undefined on change.

This ensures that the agent orchestration logic correctly identifies handoff instructions even when the configuration has been edited and cleared.

Closes #12706

Copilot AI review requested due to automatic review settings April 17, 2026 01:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes an agents handoff bug where clearing handoff fields in the UI produced empty strings ("") that prevented backend defaults (e.g., default promptKey = "instructions") from being applied.

Changes:

  • Backend: Normalize ""undefined for graphEdgeSchema fields (description, prompt, promptKey) via Zod transforms.
  • Frontend: Normalize cleared handoff inputs to undefined in AgentHandoffs.tsx change handlers.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/api/src/agents/validation.ts Adds Zod transforms to treat empty-string edge fields as unset so backend defaulting works.
client/src/components/SidePanel/Agents/Advanced/AgentHandoffs.tsx Normalizes cleared handoff form inputs to undefined before saving edges.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

placeholder={localize('com_ui_agent_handoff_prompt_placeholder')}
value={typeof edge.prompt === 'string' ? edge.prompt : ''}
onChange={(e) => updateHandoffDetailsAt(idx, { prompt: e.target.value })}
onChange={(e) => updateHandoffDetailsAt(idx, { prompt: e.target.value?.trim() || undefined })}
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

The prompt textarea handler calls .trim() before saving. That changes user-authored prompt content (e.g., leading/trailing newlines/spaces used for formatting) rather than just normalizing an “empty” value. Consider preserving the raw textarea value and only mapping an empty string to undefined (or use a dedicated empty-string check) so prompt content isn’t mutated.

Suggested change
onChange={(e) => updateHandoffDetailsAt(idx, { prompt: e.target.value?.trim() || undefined })}
onChange={(e) =>
updateHandoffDetailsAt(idx, {
prompt: e.target.value === '' ? undefined : e.target.value,
})
}

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +51
description: z.string().optional().transform((v) => (v === '' ? undefined : v)),
edgeType: z.enum(['handoff', 'direct']).optional(),
prompt: z.union([z.string(), z.function()]).optional(),
prompt: z.union([z.string(), z.function()]).optional().transform((v) => (v === '' ? undefined : v)),
excludeResults: z.boolean().optional(),
promptKey: z.string().optional(),
promptKey: z.string().optional().transform((v) => (v === '' ? undefined : v)),
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

There’s no regression test covering the new empty-string normalization for edge fields (description/prompt/promptKey). Adding a unit test that parses an agent update payload containing edges: [{..., promptKey: ''}] and asserts the parsed result omits/undefines those fields would help prevent this bug from reappearing (and ensures the schema+controller pipeline behaves as intended).

Copilot uses AI. Check for mistakes.
@danny-avila danny-avila changed the base branch from main to dev April 17, 2026 02:30
@danny-avila
Copy link
Copy Markdown
Owner

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c2d8618037

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/components/SidePanel/Agents/Advanced/AgentHandoffs.tsx Outdated
@danny-avila
Copy link
Copy Markdown
Owner

Please address ESLint issues and Codex review comment

@xxsLuna xxsLuna force-pushed the fix/agent-handoff-prompt-normalization branch from 5ba697b to 9927c6a Compare April 17, 2026 04:29
@xxsLuna
Copy link
Copy Markdown
Author

xxsLuna commented Apr 17, 2026

I've addressed the ESLint (Prettier) issues and the Codex review feedback (preserving whitespace in the prompt). Please review the updated changes. Thank you!

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.

bug: Agent handoff instructions fail when parameter name or prompt is cleared in UI

3 participants