mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
feat: share the tool catalog with voice
This commit is contained in:
1 parent
0953ebb026
commit
1a03e7483d
19 files changed
+288
-15
No files matched your search
@@ -0,0 +1,28 @@
|
||||
/** Function-calling adapter for a tool catalog: tool records and results. */
|
||||
|
||||
/** Tools as `{ type: 'function', name, description, parameters }` records. */
|
||||
export function toFunctionTools(tools, { exclude = [] } = {}) {
|
||||
const skipped = new Set(exclude);
|
||||
return tools
|
||||
.filter((tool) => !skipped.has(tool.name))
|
||||
.map((tool) => ({
|
||||
type: 'function',
|
||||
name: tool.name,
|
||||
description: tool.description,
|
||||
parameters: structuredClone(tool.inputSchema),
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* A tool result as one JSON function output. Images are counted rather than
|
||||
* sent, since function outputs carry text.
|
||||
*/
|
||||
export function toFunctionOutput(name, result) {
|
||||
return {
|
||||
ok: true,
|
||||
tool: name,
|
||||
summary: result.summary,
|
||||
data: result.data,
|
||||
...(result.images?.length ? { images_omitted: result.images.length } : {}),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { coreTools, toFunctionOutput, toFunctionTools } from './index.js';
|
||||
|
||||
test('catalog tools become independent function records', () => {
|
||||
const records = toFunctionTools(coreTools, {
|
||||
exclude: ['open_in_gods_eye_view'],
|
||||
});
|
||||
assert.equal(records.length, coreTools.length - 1);
|
||||
assert.ok(!records.some((tool) => tool.name === 'open_in_gods_eye_view'));
|
||||
const weather = records.find((tool) => tool.name === 'get_weather');
|
||||
const source = coreTools.find((tool) => tool.name === 'get_weather');
|
||||
assert.deepEqual(Object.keys(weather), [
|
||||
'type',
|
||||
'name',
|
||||
'description',
|
||||
'parameters',
|
||||
]);
|
||||
assert.equal(weather.type, 'function');
|
||||
assert.equal(weather.description, source.description);
|
||||
assert.deepEqual(weather.parameters, source.inputSchema);
|
||||
assert.notEqual(weather.parameters, source.inputSchema);
|
||||
weather.parameters.properties.location.description = 'changed';
|
||||
assert.notEqual(
|
||||
source.inputSchema.properties.location.description,
|
||||
'changed',
|
||||
);
|
||||
assert.ok(records.every((tool) => tool.parameters.type === 'object'));
|
||||
});
|
||||
|
||||
test('results become function outputs without image data', () => {
|
||||
assert.deepEqual(
|
||||
toFunctionOutput('get_wind', { summary: 'Calm.', data: { calm: true } }),
|
||||
{ ok: true, tool: 'get_wind', summary: 'Calm.', data: { calm: true } },
|
||||
);
|
||||
assert.deepEqual(
|
||||
toFunctionOutput('get_weather_map', {
|
||||
summary: 'Radar.',
|
||||
data: {},
|
||||
images: [{ mimeType: 'image/png', data: 'AAAA' }],
|
||||
}),
|
||||
{
|
||||
ok: true,
|
||||
tool: 'get_weather_map',
|
||||
summary: 'Radar.',
|
||||
data: {},
|
||||
images_omitted: 1,
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -67,6 +67,7 @@ export {
|
||||
distanceKm,
|
||||
} from './area.js';
|
||||
export { LIMIT_SCHEMA, DEFAULT_LIMIT, MAX_LIMIT, capRows } from './results.js';
|
||||
export { toFunctionOutput, toFunctionTools } from './functions.js';
|
||||
export {
|
||||
createGeocodePlaceService,
|
||||
createPlaceSearchService,
|
||||
|
||||
Reference in new issue
Block a user