mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-26 04:43:56 +02:00
feat: add tool metadata registry with human-readable labels
Add a builtin tool label registry mapping all ~30 official SDK tool IDs to human-readable display names. Update listApprovalToolDefinitions to resolve labels from the registry instead of showing raw tool IDs like read_bash or fetch_copilot_cli_documentation. Expand the fallback runtime tool catalog from 6 to 23 non-internal standard tools. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -89,15 +89,82 @@ const lspApprovalOperations = [
|
|||||||
{ suffix: 'references', label: 'References' },
|
{ suffix: 'references', label: 'References' },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
// Human-readable labels for built-in runtime tools.
|
||||||
|
// Both bash and powershell variants are included for forward compatibility.
|
||||||
|
const builtinToolLabels: ReadonlyMap<string, string> = new Map([
|
||||||
|
// Shell tools
|
||||||
|
['bash', 'Execute shell commands'],
|
||||||
|
['powershell', 'Execute shell commands'],
|
||||||
|
['read_bash', 'Read shell output'],
|
||||||
|
['read_powershell', 'Read shell output'],
|
||||||
|
['write_bash', 'Write shell input'],
|
||||||
|
['write_powershell', 'Write shell input'],
|
||||||
|
['stop_bash', 'Stop shell session'],
|
||||||
|
['stop_powershell', 'Stop shell session'],
|
||||||
|
['list_bash', 'List shell sessions'],
|
||||||
|
['list_powershell', 'List shell sessions'],
|
||||||
|
// File tools
|
||||||
|
['view', 'View files'],
|
||||||
|
['create', 'Create files'],
|
||||||
|
['edit', 'Edit files'],
|
||||||
|
['apply_patch', 'Apply patch'],
|
||||||
|
// Search tools
|
||||||
|
['grep', 'Search file contents'],
|
||||||
|
['rg', 'Search file contents'],
|
||||||
|
['glob', 'Find files by pattern'],
|
||||||
|
// Agent tools
|
||||||
|
['task', 'Run sub-agent'],
|
||||||
|
['read_agent', 'Read agent results'],
|
||||||
|
['list_agents', 'List agents'],
|
||||||
|
// Web tools
|
||||||
|
['web_fetch', 'Fetch web content'],
|
||||||
|
['web_search', 'Search the web'],
|
||||||
|
// Other tools
|
||||||
|
['skill', 'Invoke skill'],
|
||||||
|
['show_file', 'Show file'],
|
||||||
|
['fetch_copilot_cli_documentation', 'Fetch CLI docs'],
|
||||||
|
['update_todo', 'Update checklist'],
|
||||||
|
['store_memory', 'Store memory'],
|
||||||
|
['sql', 'Query session data'],
|
||||||
|
['lsp', 'Language server'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
export function resolveToolLabel(toolId: string): string {
|
||||||
|
return builtinToolLabels.get(toolId) ?? toolId;
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback runtime tools used before sidecar capabilities are loaded or when the
|
// Fallback runtime tools used before sidecar capabilities are loaded or when the
|
||||||
// CLI cannot report its built-in tool catalog dynamically.
|
// CLI cannot report its built-in tool catalog dynamically.
|
||||||
const fallbackRuntimeApprovalTools: ReadonlyArray<RuntimeToolDefinition> = [
|
const fallbackRuntimeApprovalTools: ReadonlyArray<RuntimeToolDefinition> = [
|
||||||
{ id: 'glob', label: 'glob', description: 'Match files by glob pattern.' },
|
// Shell tools (bash variants — SDK reports these on all platforms)
|
||||||
{ id: 'lsp', label: 'lsp', description: 'Query configured language servers.' },
|
{ id: 'bash', label: 'Execute shell commands' },
|
||||||
{ id: 'rg', label: 'rg', description: 'Search file contents with ripgrep.' },
|
{ id: 'read_bash', label: 'Read shell output' },
|
||||||
{ id: 'view', label: 'view', description: 'Read files and list directories.' },
|
{ id: 'write_bash', label: 'Write shell input' },
|
||||||
{ id: 'web_fetch', label: 'web_fetch', description: 'Fetch content from a URL.' },
|
{ id: 'stop_bash', label: 'Stop shell session' },
|
||||||
{ id: 'web_search', label: 'web_search', description: 'Search the web for current information.' },
|
{ id: 'list_bash', label: 'List shell sessions' },
|
||||||
|
// File tools
|
||||||
|
{ id: 'view', label: 'View files' },
|
||||||
|
{ id: 'create', label: 'Create files' },
|
||||||
|
{ id: 'edit', label: 'Edit files' },
|
||||||
|
{ id: 'apply_patch', label: 'Apply patch' },
|
||||||
|
// Search tools
|
||||||
|
{ id: 'grep', label: 'Search file contents' },
|
||||||
|
{ id: 'glob', label: 'Find files by pattern' },
|
||||||
|
// Agent tools
|
||||||
|
{ id: 'task', label: 'Run sub-agent' },
|
||||||
|
{ id: 'read_agent', label: 'Read agent results' },
|
||||||
|
{ id: 'list_agents', label: 'List agents' },
|
||||||
|
// Web tools
|
||||||
|
{ id: 'web_fetch', label: 'Fetch web content' },
|
||||||
|
{ id: 'web_search', label: 'Search the web' },
|
||||||
|
// Other tools
|
||||||
|
{ id: 'skill', label: 'Invoke skill' },
|
||||||
|
{ id: 'show_file', label: 'Show file' },
|
||||||
|
{ id: 'fetch_copilot_cli_documentation', label: 'Fetch CLI docs' },
|
||||||
|
{ id: 'update_todo', label: 'Update checklist' },
|
||||||
|
{ id: 'store_memory', label: 'Store memory' },
|
||||||
|
{ id: 'sql', label: 'Query session data' },
|
||||||
|
{ id: 'lsp', label: 'Language server' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export function createWorkspaceSettings(): WorkspaceSettings {
|
export function createWorkspaceSettings(): WorkspaceSettings {
|
||||||
@@ -171,7 +238,7 @@ export function listApprovalToolDefinitions(
|
|||||||
for (const tool of runtimeApprovalTools) {
|
for (const tool of runtimeApprovalTools) {
|
||||||
registerApprovalTool(toolsById, {
|
registerApprovalTool(toolsById, {
|
||||||
id: tool.id,
|
id: tool.id,
|
||||||
label: tool.label,
|
label: resolveToolLabel(tool.id),
|
||||||
description: tool.description,
|
description: tool.description,
|
||||||
kind: 'builtin',
|
kind: 'builtin',
|
||||||
providerId: `builtin:${tool.id}`,
|
providerId: `builtin:${tool.id}`,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
listApprovalToolDefinitions,
|
listApprovalToolDefinitions,
|
||||||
normalizeWorkspaceSettings,
|
normalizeWorkspaceSettings,
|
||||||
resolveProjectToolingSettings,
|
resolveProjectToolingSettings,
|
||||||
|
resolveToolLabel,
|
||||||
resolveWorkspaceToolingSettings,
|
resolveWorkspaceToolingSettings,
|
||||||
validateLspProfileDefinition,
|
validateLspProfileDefinition,
|
||||||
validateMcpServerDefinition,
|
validateMcpServerDefinition,
|
||||||
@@ -206,8 +207,7 @@ describe('tooling settings helpers', () => {
|
|||||||
|
|
||||||
expect(tools).toContainEqual({
|
expect(tools).toContainEqual({
|
||||||
id: 'web_fetch',
|
id: 'web_fetch',
|
||||||
label: 'web_fetch',
|
label: 'Fetch web content',
|
||||||
description: 'Fetch content from a URL.',
|
|
||||||
kind: 'builtin',
|
kind: 'builtin',
|
||||||
providerIds: ['builtin:web_fetch'],
|
providerIds: ['builtin:web_fetch'],
|
||||||
providerNames: ['Built-in'],
|
providerNames: ['Built-in'],
|
||||||
@@ -251,6 +251,41 @@ describe('tooling settings helpers', () => {
|
|||||||
expect(tools.some((tool) => tool.id === 'web_fetch')).toBe(false);
|
expect(tools.some((tool) => tool.id === 'web_fetch')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('resolves human-readable labels from the tool metadata registry', () => {
|
||||||
|
expect(resolveToolLabel('bash')).toBe('Execute shell commands');
|
||||||
|
expect(resolveToolLabel('read_bash')).toBe('Read shell output');
|
||||||
|
expect(resolveToolLabel('web_fetch')).toBe('Fetch web content');
|
||||||
|
expect(resolveToolLabel('fetch_copilot_cli_documentation')).toBe('Fetch CLI docs');
|
||||||
|
expect(resolveToolLabel('glob')).toBe('Find files by pattern');
|
||||||
|
expect(resolveToolLabel('lsp')).toBe('Language server');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('passes through unknown tool IDs as labels', () => {
|
||||||
|
expect(resolveToolLabel('my_custom_tool')).toBe('my_custom_tool');
|
||||||
|
expect(resolveToolLabel('')).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('fallback catalog includes all standard non-internal tools with friendly labels', () => {
|
||||||
|
const tools = listApprovalToolDefinitions({ mcpServers: [], lspProfiles: [] });
|
||||||
|
const builtinTools = tools.filter((t) => t.kind === 'builtin');
|
||||||
|
|
||||||
|
expect(builtinTools.length).toBeGreaterThanOrEqual(20);
|
||||||
|
expect(builtinTools.some((t) => t.id === 'bash')).toBe(true);
|
||||||
|
expect(builtinTools.some((t) => t.id === 'web_fetch')).toBe(true);
|
||||||
|
expect(builtinTools.some((t) => t.id === 'task')).toBe(true);
|
||||||
|
expect(builtinTools.some((t) => t.id === 'store_memory')).toBe(true);
|
||||||
|
|
||||||
|
// Labels should be human-readable, not raw IDs
|
||||||
|
const bashTool = builtinTools.find((t) => t.id === 'bash');
|
||||||
|
expect(bashTool?.label).toBe('Execute shell commands');
|
||||||
|
|
||||||
|
// Internal tools should not appear in the fallback
|
||||||
|
expect(builtinTools.some((t) => t.id === 'ask_user')).toBe(false);
|
||||||
|
expect(builtinTools.some((t) => t.id === 'report_intent')).toBe(false);
|
||||||
|
expect(builtinTools.some((t) => t.id === 'task_complete')).toBe(false);
|
||||||
|
expect(builtinTools.some((t) => t.id === 'exit_plan_mode')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
test('resolves workspace and project tooling with accepted discovered MCP servers', () => {
|
test('resolves workspace and project tooling with accepted discovered MCP servers', () => {
|
||||||
const workspaceTooling = resolveWorkspaceToolingSettings(normalizeWorkspaceSettings({
|
const workspaceTooling = resolveWorkspaceToolingSettings(normalizeWorkspaceSettings({
|
||||||
tooling: {
|
tooling: {
|
||||||
|
|||||||
Reference in New Issue
Block a user