Skip to content

Conversation

@hkfires
Copy link
Collaborator

@hkfires hkfires commented Dec 4, 2025

No description provided.

@gemini-code-assist
Copy link

Summary of Changes

Hello @hkfires, 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 refines the configuration management for the AmpModule. It introduces mechanisms to ensure that the module's internal API key is correctly refreshed upon configuration updates and expands the configuration watcher to provide comprehensive details on changes to AmpCode settings, including model mappings. This improves the robustness and observability of AmpCode configuration handling.

Highlights

  • AMP API Key Refresh: The AmpModule now explicitly updates its internal API key from the configuration settings when the configuration is updated, ensuring the latest key is always used.
  • MultiSourceSecret Key Update Method: A new method UpdateExplicitKey was added to MultiSourceSecret to allow external components to refresh the stored API key and invalidate its cache, protected by a mutex for concurrency safety.
  • AMP Configuration Change Tracking: The configuration watcher now includes detailed tracking for AmpCode settings, such as UpstreamURL, UpstreamAPIKey (redacted), RestrictManagementToLocalhost, and ModelMappings, providing clear summaries of these changes.
  • Model Mapping Summarization: A new utility function summarizeAmpModelMappings was introduced to create a hash-based summary of AMP model mappings, enabling efficient detection of changes in these mappings within the configuration watcher.
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

@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 introduces changes to support hot-reloading of Amp-related configurations, specifically the upstream API key and model mappings. The changes are logical, but I've identified a few areas for improvement. There's a redundant function call, an opportunity to use more idiomatic Go for mutex handling, and a significant issue with the hashing logic for model mappings that could lead to collisions. My review includes suggestions to address these points.

Comment on lines +578 to +600
func summarizeAmpModelMappings(mappings []config.AmpModelMapping) ampModelMappingsSummary {
if len(mappings) == 0 {
return ampModelMappingsSummary{}
}
entries := make([]string, 0, len(mappings))
for _, mapping := range mappings {
from := strings.TrimSpace(mapping.From)
to := strings.TrimSpace(mapping.To)
if from == "" && to == "" {
continue
}
entries = append(entries, from+"->"+to)
}
if len(entries) == 0 {
return ampModelMappingsSummary{}
}
sort.Strings(entries)
sum := sha256.Sum256([]byte(strings.Join(entries, "|")))
return ampModelMappingsSummary{
hash: hex.EncodeToString(sum[:]),
count: len(entries),
}
}

Choose a reason for hiding this comment

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

high

The current method of creating a hash for model mappings by concatenating strings with -> and | is brittle and can lead to hash collisions if model names contain these characters. For example, the list of mappings [{from: "a", to: "b|c"}, {from: "d", to: "e"}] would produce the same hash as [{from: "a", to: "b"}, {from: "c|d", to: "e"}]. A more robust approach, consistent with other hashing functions in this file (e.g., computeExcludedModelsHash), is to marshal the structured data into JSON before hashing. This ensures an unambiguous representation.

func summarizeAmpModelMappings(mappings []config.AmpModelMapping) ampModelMappingsSummary {
	if len(mappings) == 0 {
		return ampModelMappingsSummary{}
	}
	type mappingForHash struct {
		From string `json:"from"`
		To   string `json:"to"`
	}
	canonical := make([]mappingForHash, 0, len(mappings))
	for _, mapping := range mappings {
		from := strings.TrimSpace(mapping.From)
		to := strings.TrimSpace(mapping.To)
		if from == "" && to == "" {
			continue
		}
		canonical = append(canonical, mappingForHash{From: from, To: to})
	}
	if len(canonical) == 0 {
		return ampModelMappingsSummary{}
	}
	sort.Slice(canonical, func(i, j int) bool {
		if canonical[i].From != canonical[j].From {
			return canonical[i].From < canonical[j].From
		}
		return canonical[i].To < canonical[j].To
	})
	data, err := json.Marshal(canonical)
	if err != nil {
		return ampModelMappingsSummary{count: len(canonical)}
	}
	sum := sha256.Sum256(data)
	return ampModelMappingsSummary{
		hash:  hex.EncodeToString(sum[:]),
		count: len(canonical),
	}
}

if m.secretSource != nil {
if ms, ok := m.secretSource.(*MultiSourceSecret); ok {
ms.UpdateExplicitKey(settings.UpstreamAPIKey)
ms.InvalidateCache()

Choose a reason for hiding this comment

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

medium

The call to ms.InvalidateCache() is redundant because ms.UpdateExplicitKey() already clears the cache by setting it to nil. You can safely remove this line to avoid unnecessary code.

Comment on lines +147 to +150
s.mu.Lock()
s.explicitKey = strings.TrimSpace(key)
s.cache = nil
s.mu.Unlock()

Choose a reason for hiding this comment

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

medium

For safer concurrency and to follow idiomatic Go, it's best to use defer to unlock the mutex immediately after locking it. This guarantees that the mutex will be unlocked even if a panic occurs within the function.

Suggested change
s.mu.Lock()
s.explicitKey = strings.TrimSpace(key)
s.cache = nil
s.mu.Unlock()
s.mu.Lock()
defer s.mu.Unlock()
s.explicitKey = strings.TrimSpace(key)
s.cache = nil

@luispater luispater merged commit b87b9b4 into dev Dec 4, 2025
1 check passed
@luispater luispater deleted the amp branch December 4, 2025 12:52
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.

3 participants