feat(tools): add get_location built-in agent tool

This commit is contained in:
Marco Beretta 2026-06-15 18:34:43 +02:00
parent 78fdebf226
commit 362ac158d6
No known key found for this signature in database
GPG key ID: D918033D8E74CC11
6 changed files with 92 additions and 0 deletions

View file

@ -12,6 +12,7 @@ const TraversaalSearch = require('./structured/TraversaalSearch');
const createOpenAIImageTools = require('./structured/OpenAIImageTools');
const TavilySearchResults = require('./structured/TavilySearchResults');
const createGeminiImageTool = require('./structured/GeminiImageGen');
const createLocationTool = require('./structured/GetLocation');
module.exports = {
...manifest,
@ -27,4 +28,5 @@ module.exports = {
TavilySearchResults,
createOpenAIImageTools,
createGeminiImageTool,
createLocationTool,
};

View file

@ -166,5 +166,12 @@
"optional": true
}
]
},
{
"name": "Get Location",
"pluginKey": "get_location",
"description": "Returns the user's shared location (place, coordinates, timezone) so the assistant can tailor language, units, and regional context.",
"icon": "assets/google-search.svg",
"authConfig": []
}
]

View file

@ -0,0 +1,29 @@
const { tool } = require('@librechat/agents/langchain/tools');
const { formatLocationToolResult } = require('@librechat/api');
const locationSchema = {
type: 'object',
properties: {},
required: [],
};
/**
* Factory for the `get_location` tool, bound to the current request/user.
* @param {{ userId?: string, req?: import('express').Request }} params
* @returns {Promise<import('@librechat/agents/langchain/tools').DynamicStructuredTool>}
*/
module.exports = async function createLocationTool({ req } = {}) {
return tool(
async () => {
const featureEnabled = req?.config?.location?.enabled !== false;
const location = req?.user?.personalization?.location;
return formatLocationToolResult(location, { featureEnabled });
},
{
name: 'get_location',
description:
"Returns the user's current location (place, coordinates, timezone) when they have shared it. Use it to tailor language, regional context, units, or weather lookups.",
schema: locationSchema,
},
);
};

View file

@ -0,0 +1,40 @@
const createLocationTool = require('./GetLocation');
const makeReq = ({ location, featureEnabled = true } = {}) => ({
config: { location: { enabled: featureEnabled } },
user: { id: 'user-1', personalization: location ? { location } : {} },
});
describe('createLocationTool', () => {
it('returns the user location when enabled', async () => {
const tool = await createLocationTool({
userId: 'user-1',
req: makeReq({
location: {
enabled: true,
source: 'manual',
manual: 'Berlin, Germany',
timezone: 'Europe/Berlin',
},
}),
});
const result = await tool.invoke({});
expect(result).toContain('Berlin, Germany');
expect(result).toContain('Europe/Berlin');
});
it('returns a not-shared message when the user has not opted in', async () => {
const tool = await createLocationTool({ userId: 'user-1', req: makeReq({}) });
const result = await tool.invoke({});
expect(result).toMatch(/has not shared/i);
});
it('returns a disabled message when the admin flag is off', async () => {
const tool = await createLocationTool({
userId: 'user-1',
req: makeReq({ location: { enabled: true, manual: 'X' }, featureEnabled: false }),
});
const result = await tool.invoke({});
expect(result).toMatch(/disabled/i);
});
});

View file

@ -34,6 +34,7 @@ const {
TavilySearchResults,
createGeminiImageTool,
createOpenAIImageTools,
createLocationTool,
} = require('../');
const {
createMCPTool,
@ -230,6 +231,9 @@ const loadTools = async ({
fileStrategy,
});
},
get_location: async () => {
return createLocationTool({ userId: user, req: options.req });
},
};
const requestedTools = {};

View file

@ -445,6 +445,16 @@ export const toolDefinitions: Record<string, ToolRegistryDefinition> = {
toolType: 'builtin',
responseFormat: geminiToolkit.gemini_image_gen.responseFormat,
},
get_location: {
name: 'get_location',
description: "Returns the user's current location (place, coordinates, timezone) when shared.",
schema: {
type: 'object',
properties: {},
required: [],
},
toolType: 'builtin',
},
};
/**