Skip to content

Conversation

@jussi-sa
Copy link
Contributor

@jussi-sa jussi-sa commented Aug 27, 2025

Description

  • Renamed TilesetComparisonTool to StyleComparisonTool for better clarity
    • Refactored tool to use Mapbox Agent API endpoint instead of generating HTML locally
    • Simplified implementation by removing HTML template and map configuration parameters

New Feature: Style Comparison Tool

API Integration:

  • Changed output from HTML generation to URL generation
  • Now uses https://agent.mapbox.com/tools/style-compare endpoint
  • Returns a comparison URL with query parameters instead of HTML content

Schema Simplification:

  • Removed unused map parameters (center, zoom, bearing, pitch, title)
  • Kept only essential parameters: before, after, and accessToken
  • Updated parameter descriptions to clarify requirements

Test Updates:

  • Updated all tests to expect URL output instead of HTML
  • Added test for proper URL parameter encoding
  • Maintained existing token validation and error handling tests

Breaking Changes

  • Tool now returns a URL string instead of HTML content
  • Removed support for map initialization parameters
  • Changed tool description to reflect new functionality

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com


Testing


Checklist

  • Code has been tested locally
  • Unit tests have been added or updated
  • Documentation has been updated if needed

Additional Notes

@jussi-sa jussi-sa requested a review from a team as a code owner August 27, 2025 16:14
@jussi-sa jussi-sa changed the title Tileset comparison Style comparison Aug 29, 2025
private async ensurePublicToken(providedToken?: string): Promise<string> {
// If no token provided, try to get one from the account
if (!providedToken) {
const fetchedToken = await this.fetchPublicToken();
Copy link
Member

Choose a reason for hiding this comment

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

🤔 I’m wondering if we really need to fetch a token here, since that would increase this tool’s complexity. If the client already knows we have token tools, and calling this tool requires a token, won’t the agent try to obtain the token by itself? If so, we probably don’t need this fallback solution. Another drawback is that if we make changes to the token tool, it’s quite easy to forget to update this part accordingly.
What do you think?

Copy link
Contributor Author

@jussi-sa jussi-sa Aug 29, 2025

Choose a reason for hiding this comment

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

When I was testing this tool, the challenge was that the model would always try to call this tool with the configured MAPBOX_ACCESS_TOKEN, which is a secret token. If we don't have this logic in the tool, this is what would usually happen:

  1. prompt "compare minimalistic and halloween theme"
    -> calls tool with the configured MAPBOX_ACCESS_TOKEN, which is an sk. token
  2. open the URL -> fail to load GL JS map, because sk. token is not allowed in GL JS map

I think for the same reason we have this kind of logic in preview style tool:

const tokensResult = await listTokensTool.run({

It's a dependency, just to avoid the model choosing a secret token instead of public one.

But in this situation, we are producing a URL, and the model doesn't know what happens when we open the URL. The user would have to prompt again "hey create another url using public token"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe we can try to describe the input in the schema, to always use a .pk token. I will see if that works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the schema so that the access_token now has a description, which instructs the models to use s pk. token - this seems to work very well! Tested in Claude, the model will now find a .pk token first, and then create the comparison:

image


// If it's a secret token, try to get a public token instead
if (providedToken.startsWith('sk.')) {
const publicToken = await this.fetchPublicToken();
Copy link
Member

Choose a reason for hiding this comment

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

🤔 When this tool is called with a private token, it switches the private token to a public token internally, and the caller won’t notice. Is that really the design we want?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is related to my comment above. .sk token will never work with this tool, because GL JS map will fail to load with a secret token. It is just a guard so that the model doesn't run in to errors

params.append('before', beforeStyleId);
params.append('after', afterStyleId);

const url = `https://agent.mapbox.com/tools/style-compare?${params.toString()}`;
Copy link
Member

Choose a reason for hiding this comment

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

[Nit] A demo url is, access_token=pk.xxx&before=mapbox/streets-v11&after=mapbox/outdoors-v12#10/37.7/-122.4 we could also consider to add zoom(i.e. 10 in this case), latitude, latitude as an optional parameter for this tool

@jussi-sa jussi-sa merged commit d023bd6 into main Aug 29, 2025
1 check passed
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.

2 participants