Skip to content

Conversation

@MichaelDoyle
Copy link
Member

@MichaelDoyle MichaelDoyle commented Jan 4, 2026

This PR will properly handle rendering dotprompt(s) with multiple "messages" within, e.g. system prompts, message history, etc.

The primary fix is to move rendering from load time (incorrect) to execution time (correct).

However, I think there are some additional key changes (not implemented) that I believe we should make that I want opinions on, specifically with regards to bringing Go into parity with the TS implementation. I'll file an issue for these, as it will be a "breaking" change for sure.

In general, Go tries to merge all of the various options together. It tries to move system messages to the top, interleave history from various sources (Messages, PromptFn, etc), and then end with the User prompt.

In contrast, in Typescript, dotprompt has complete control over where messages (history) are rendered (via {{history}}) helper. And if you provide a MessageFn, again that also gets messages (history) as an argument and is responsible for injecting in the right place. I think without doing this, Go can interleave things in unexpected ways. Separately, any static list of messages (WithMessages), or a message function (WithMessageFn) should not try to render as templates as they do today. You want to accept these "as is", because they represent history in the former, and in the latter the Fn should have the control.

Background

Currently, there is a lot of confusion here, which has led to some PR and issue churn. See below.

Issues:

PRs:

Checklist (if applicable):

Dev UI (after changes):
image image

Fixes #3711

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @MichaelDoyle, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue in the go/ai module concerning the rendering of dotprompt templates that are designed to generate multiple messages. The changes enable the system to accurately interpret and process these multi-message outputs, ensuring that each message is assigned its appropriate role (e.g., system, user) and that non-text content is handled gracefully. This enhancement significantly improves the flexibility and accuracy of prompt engineering by allowing more complex and structured prompts to be rendered as intended, leading to more robust AI interactions.

Highlights

  • Enhanced Multi-Message Prompt Rendering: The core logic for rendering dotprompt templates has been updated to properly handle cases where a single template generates multiple distinct messages, each potentially with its own role.
  • Refined Role Assignment Logic: New logic has been introduced in renderSystemPrompt and renderUserPrompt to ensure that messages originating from system or user contexts are correctly assigned RoleSystem or RoleUser, respectively, even if the underlying dotprompt output might default to a different role or no role for single messages.
  • Updated renderPrompt Return Type: The renderPrompt function now returns a slice of Message objects ([]*Message) instead of a slice of Part objects ([]*Part), reflecting the system's ability to generate and process multiple structured messages directly from prompt templates.
  • Refactored Message Processing in renderMessages: The renderMessages function has undergone significant refactoring to correctly merge and assign roles to the newly structured Message objects returned by renderPrompt, including intelligent handling of both text and non-text parts and role inheritance.
  • Streamlined Test Suite: The test suite has been updated to reflect these changes, consolidating multi-message prompt tests and verifying the correct handling of roles and content using the new Message structure and Text() helper method.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

gemini-code-assist[bot]

This comment was marked as outdated.

@MichaelDoyle MichaelDoyle changed the title fix(go/ai): properly render dotprompt multi-messages prompts fix(go/ai): properly render dotprompt multi-message prompts Jan 4, 2026
@MichaelDoyle MichaelDoyle force-pushed the go-dotprompt-role branch 4 times, most recently from e6db25a to 6d9391b Compare January 5, 2026 16:49
@MichaelDoyle
Copy link
Member Author

/gemini review

gemini-code-assist[bot]

This comment was marked as outdated.

@MichaelDoyle MichaelDoyle marked this pull request as ready for review January 7, 2026 15:03
@MichaelDoyle
Copy link
Member Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively refactors prompt rendering to occur at execution time, which correctly handles multi-message prompts defined in .prompt files. The core logic is sound, moving from pre-parsing templates at load time to a deferred rendering approach. This is achieved by modifying renderPrompt to work with []*Message instead of []*Part, thereby preserving message structures and roles. The associated test and sample code changes align well with this new approach. Overall, this is a solid improvement that increases correctness and simplifies the prompt loading logic.

@apascal07
Copy link
Collaborator

Thanks Mike!!

@apascal07 apascal07 merged commit 741bb54 into main Jan 7, 2026
6 checks passed
@apascal07 apascal07 deleted the go-dotprompt-role branch January 7, 2026 18:17
Zereker added a commit to Zereker/genkit that referenced this pull request Jan 8, 2026
Add TestLoadPromptTemplateVariableSubstitution to verify that template
variables are correctly substituted with actual input values at execution
time, not load time.

This test covers:
1. Single role prompts with template variables
2. Multi-role prompts (system + user) with template variables
3. Verification that consecutive renders use their own input values

Related to firebase#3924 (fixed by firebase#4035)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Go] Genkit ignores dotprompt-defined roles

2 participants