Skip to content

Conversation

@BeautyyuYanli
Copy link

@BeautyyuYanli BeautyyuYanli commented Jan 26, 2026

This is part of langgenius/dify-official-plugins#2492

Summary

Adds optional opaque_body passthrough for prompt messages so provider-specific metadata can be carried through without schema changes.

Changes

  • Add opaque_body to PromptMessage and PromptMessageContent (omitempty).
  • Preserve opaque_body in PromptMessage JSON unmarshal.
  • Extend tests to cover message-level and content-level opaque_body.

Testing

  • go test ./pkg/entities/model_entities -run TestFullFunctionPromptMessage

@dosubot dosubot bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jan 26, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @BeautyyuYanli, 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 introduces a flexible mechanism to embed provider-specific metadata directly within prompt messages. By adding an opaque_body field, the system can now carry through external data without requiring modifications to the primary message schema, enhancing interoperability and extensibility for various LLM providers. This change ensures that any arbitrary JSON data provided in this field is preserved during serialization and deserialization.

Highlights

  • Schema Extension: Added an OpaqueBody field of type json.RawMessage to both the PromptMessage and PromptMessageContent structs. This allows for the inclusion of arbitrary, provider-specific metadata without altering the core schema.
  • JSON Unmarshalling: Implemented logic within the PromptMessage's UnmarshalJSON method to correctly parse and preserve the opaque_body field when deserializing JSON data.
  • Test Coverage: Extended existing test cases in llm_test.go to validate the proper handling and unmarshalling of the opaque_body field at both the message level (PromptMessage) and content level (PromptMessageContent).

🧠 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.

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 adds an optional opaque_body field to PromptMessage and PromptMessageContent to allow for passthrough of provider-specific metadata. The changes include updating the struct definitions, modifying the custom UnmarshalJSON for PromptMessage to handle the new field, and extending tests to cover the new functionality. The implementation is correct, but I've identified a significant opportunity to improve the maintainability of the custom UnmarshalJSON function in llm.go. My feedback includes a suggestion to refactor this function to make it more robust and easier to manage in the future.

Comment on lines +181 to +183
if opaqueBody, ok := raw["opaque_body"]; ok {
p.OpaqueBody = opaqueBody
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

While this correctly handles the opaque_body field, the overall approach in UnmarshalJSON of manually unmarshalling each field from a map is brittle and hard to maintain. As new fields are added to PromptMessage, this function will need to be updated each time, increasing the risk of errors.

A more robust and idiomatic Go approach is to use a struct alias. This lets you leverage the default JSON unmarshaling for all standard fields and only write custom logic for the fields that need special handling (in this case, Content). This would automatically handle opaque_body and any future fields added to the struct.

I recommend refactoring the entire UnmarshalJSON function as follows:

func (p *PromptMessage) UnmarshalJSON(data []byte) error {
	// Use an alias to avoid recursion with UnmarshalJSON.
	type Alias PromptMessage
	aux := &struct {
		// Capture Content as raw JSON to handle its dual type.
		Content json.RawMessage `json:"content"`
		*Alias
	}{
		Alias: (*Alias)(p),
	}

	if err := json.Unmarshal(data, &aux); err != nil {
		return err
	}

	// The original implementation required 'role' and 'content'.
	// The validator will catch this later, but checking here provides an earlier, clearer error.
	if p.Role == "" {
		return errors.New("role field is required")
	}
	if len(aux.Content) == 0 || string(aux.Content) == "null" {
		return errors.New("content field is required")
	}

	// Try to unmarshal content as a string.
	var s string
	if err := json.Unmarshal(aux.Content, &s); err == nil {
		p.Content = s
		return nil
	}

	// If not a string, try as a slice of PromptMessageContent.
	var slice []PromptMessageContent
	if err := json.Unmarshal(aux.Content, &slice); err != nil {
		return err // Invalid content format
	}
	p.Content = slice

	return nil
}

This change would make the code more maintainable and less error-prone for future modifications.

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

Labels

enhancement New feature or request size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants