Skip to content

Feature/tool restructuring#83

Merged
davi0015 merged 19 commits into
mainfrom
feature/tool-restructuring
Jul 9, 2026
Merged

Feature/tool restructuring#83
davi0015 merged 19 commits into
mainfrom
feature/tool-restructuring

Conversation

@davi0015

@davi0015 davi0015 commented Jul 9, 2026

Copy link
Copy Markdown
Owner

No description provided.

davi0015 added 19 commits July 2, 2026 14:51
Most resultWrapper components returned null for tool_request state,
which hid pending tools in a batch. With concurrent terminal execution,
tools stay in tool_request longer while others are being approved,
making the second tool's box invisible and the chat stuck.

All resultWrapper components now render a header for tool_request and
running_now states. Also removed hardcoded isOpen on CommandTool that
prevented collapsing terminal output, and added load_skill to the
title/desc/resultWrapper UI mappings.
Electron-main no longer calls availableTools() or knows about chatMode
or mcpTools. The browser-layer service (sendLLMMessageService) computes
the tool list via availableTools(chatMode, mcpTools) and passes the
resolved InternalToolInfo[] across the IPC boundary as 'tools'.

This decouples electron-main from tool definitions, enabling the tool
descriptions to move from common/ to browser/ in subsequent commits.

Also adds the tool-restructuring design doc.
…, registry)

Creates browser/tools/toolTypes.tsx with the ToolDefinition<T> type that
co-locates all tool segments (description, approval, validate, call,
stringify, title, desc, resultWrapper) and ToolCtx for DI services.

Creates browser/tools/toolRegistry.tsx with an empty
toolDefinitionOfToolName map to be populated incrementally as tools are
converted from the old multi-map layout.
First tool migrated to the new per-file definition pattern:
- readFile.tool.ts: backend segments (description, validate, call, stringify)
- readFile.toolUI.tsx: UI segments (title, desc, resultWrapper)
- toolRegistry.ts: stores core definitions (importable from .ts)
- toolUIRegistry.tsx: stores full definitions with UI (importable from .tsx)
- toolTypes.ts: ToolDefinitionCore, ToolCtx (no JSX)
- toolUITypes.tsx: ToolDefinition (extends core with React UI types)

toolsService.ts delegates read_file to the registry. ToolResultComponents.tsx
delegates title/desc/resultWrapper to the UI registry. SidebarChat.tsx uses
getToolResultWrapper() which checks the registry first.

Split into .ts/.tsx pairs because this project's tsconfig doesn't allow .ts
files to import .tsx files (no JSX in .ts scope).
- Fix EndOfLinePreference import path in readFile.tool.ts (was 4 ../, needs 5)
- Remove unused validateStr import from readFile.tool.ts
- Remove stale availableTools import from sendLLMMessage.impl.ts
The file was emptied when toolTypes.tsx was renamed to toolUITypes.tsx.
Rewrote the content with ToolCtx and ToolDefinitionCore types.
The inline validateParams/callTool/stringOfResult for read_file are now
stubs that get overridden by the registry delegation at the end of the
constructor. The actual implementation lives in readFile.tool.ts.

Also removed unused AUTO_OUTLINE_THRESHOLD import (now in readFile.tool.ts)
and stubbed out the title entry in ToolResultComponents.tsx (title now
comes from toolUIRegistry).

Note: builtinTools.read_file in prompts.ts is kept for now — availableTools()
still reads from builtinTools to build the LLM tool list. This will be
removed in the cleanup step when availableTools() is updated to pull
descriptions from the registry.
…istry

The circular import (readFile.toolUI.tsx → ToolResultComponents.tsx →
toolUIRegistry.tsx → readFile.toolUI.tsx) crashed the workbench bundle.

Fix: ToolResultComponents.tsx no longer imports toolUIRegistry.tsx.
SidebarChat.tsx imports toolUIRegistry directly and checks it before
falling back to builtinToolNameToComponent. getTitle and toolNameToDesc
revert to using the old static maps for now — title/desc delegation
will be added in the cleanup step when shared helpers are extracted.
The UI delegation (readFile.toolUI.tsx importing from
ToolResultComponents.tsx) created a circular import that crashed the
bundle. For the POC, only the backend is delegated to the per-file
definition. The UI stays in ToolResultComponents.tsx as-is.

Deleted: toolUIRegistry.tsx, readFile.toolUI.tsx, toolUITypes.tsx
Reverted: SidebarChat.tsx back to builtinToolNameToComponent directly
Reverted: ToolResultComponents.tsx title stub back to real values

UI delegation will be added in the cleanup step after shared UI helpers
(ToolHeaderWrapper, getTitle, etc.) are extracted to a separate file.
…r at render

Title is now plain strings in readFile.tool.ts (no JSX needed).
ToolDefinitionCore gains a title field: { done: string, proposed: string, running: string }.
getTitle() checks toolDefinitionOfToolName first, applies loadingTitleWrapper to
the running string at render time. Falls back to titleOfBuiltinToolName for
unconverted tools (which already has loadingTitleWrapper baked in).
Converts 8 more tools to the per-file pattern:
- ls_dir, get_dir_tree, search_pathnames_only, search_for_files,
  search_in_file, go_to_definition, go_to_usages, read_lint_errors

Each tool file contains: description, params, approvalType, validateParams,
callTool, stringOfResult, and title (plain strings, no JSX).

The UI (resultWrapper, desc) stays in ToolResultComponents.tsx for now —
moving it requires extracting shared UI helpers to break the circular
import between tool files and ToolResultComponents.tsx.

Also exports shared helpers (validateBoolean, validateOptionalStr, isFalsy,
resolveSymbolPosition, validateProposedTerminalId, checkIfIsFolder,
validateEdits, stringifyLintErrors) from toolsService.ts, and moves
stringifyLintErrors from constructor scope to module level.

9 of 22 tools now converted.
…e.ts

Replace the old validateParams/callTool/stringOfResult entries for all 9
converted tools with throw-stubs that get overridden by the registry.
Remove unused imports (Position, getDefinitionsAtPosition,
getReferencesAtPosition, computeDirectoryTree1Deep,
stringifyDirectoryTree1Deep, MAX_CHILDREN_URIs_PAGE).

Also remove unused imports in readLintErrors.tool.ts (IMarkerService, URI,
MAX_FILE_CHARS_PAGE).
Convert create_file_or_folder, delete_file_or_folder, rename_file_or_folder,
edit_file, and rewrite_file to per-file tool definitions following the
established pattern.

- Export getLintErrors as a module-level function from toolsService.ts
  (replaces the private _getLintErrors method, now used by editFile.tool.ts
  and rewriteFile.tool.ts)
- Remove dead _getLintErrors private method and unused timeout import
- Replace inline validateParams/callTool/stringOfResult entries with
  throw-stubs for all 5 editing tools
- Add delegation blocks in ToolsService constructor
- Register all 5 tools in toolRegistry.ts

14 of 22 tools now converted.
Convert the final 8 tools (run_command, run_persistent_command,
open_persistent_terminal, kill_persistent_terminal, fetch_url,
semantic_search, search_history, load_skill) to per-file tool definitions.

All 22 builtin tools are now converted to the per-file pattern. Each tool's
description, params, approvalType, validateParams, callTool, stringOfResult,
and title live in a single .ts file under browser/tools/.

- Replace inline validateParams/callTool/stringOfResult entries with
  throw-stubs for all 8 remaining tools
- Add delegation blocks in ToolsService constructor for all 8 tools
- Remove unused imports (MAX_TERMINAL_BG_COMMAND_TIME,
  MAX_TERMINAL_INACTIVE_TIME, generateUuid, ChatMessage)
- Register all 8 tools in toolRegistry.ts

The next cleanup step can collapse the 22 repetitive if-blocks into a
generic loop, move shared helpers to toolHelpers.ts, and remove Components.tsx.
- Move all shared helper functions (isFalsy, safeFence, validateStr,
  validateURIWithRoot, validateEdits, resolveSymbolPosition, getFileOutline,
  stringifyLintErrors, getLintErrors, etc.) from toolsService.ts to a new
  browser/tools/toolHelpers.ts file
- Update all 22 tool files to import from ./toolHelpers.js instead of
  ../toolsService.js
- Slim down toolsService.ts to just the class + type aliases + interface
  (from ~960 lines to ~235 lines)
- Remove dead titleOfBuiltinToolName from ToolResultComponents.tsx (all 22
  tools now get titles from the registry)
- Simplify getTitle() to use registry directly instead of fallback chain
- Update SidebarChat.tsx to use toolDefinitionOfToolName for proposed title
- Fix URI/IFileService import paths (5 ../ → 4 ../) to match sibling files

The 22 if-blocks in the constructor are intentionally kept as-is: collapsiquires either 'any' casts or 'never' type tricks,
both of which violate the project's type safety guidelines.
Replace 22 repetitive if-blocks (132 lines) with a single Object.fromEntries
loop (12 lines) that builds all three dispatch maps from the registry.

TypeScript limitation: Object.entries on a Partial<{ [T in K]: V<T> }>
returns a union of V<T> for each T, and calling .callTool() on a union of
function types requires the intersection of all parameter types (which is
unsatisfiable). Using 'never' (the bottom type) for the lambda params
sidesteps this — 'never' is assignable to every type, so def.callTool(params,
ctx) type-checks. The result cast (as CallBuiltinTool) is standard
Object.fromEntries practice.

validateParams doesn't need this trick because its input is always
RawToolParamsObj (same for all tools).
Remove builtinTools from prompts.ts — the description, params, and name
for each tool now live only in the per-file tool definitions
(browser/tools/*.tool.ts).

Changes:
- Delete builtinTools object (~230 lines) from prompts.ts
- Move availableTools() from prompts.ts to browser/tools/toolRegistry.ts,
  where it builds InternalToolInfo[] from toolDefinitionOfToolName
- Delete dead helpers (systemToolsXMLPrompt was kept but refactored to
  accept InternalToolInfo[] instead of chatMode + mcpTools; dead
  toolCallDefinitionsXMLString was restored as a helper for it)
- Delete dead helpers (uriParam, paginationParam, terminalDescHelper,
  cwdHelper, editsTool_description) from prompts.ts
- Define builtinToolNames as explicit array instead of Object.keys(builtinTools)
- Derive BuiltinToolParamName from SnakeCaseKeys<BuiltinToolCallParams[T]>
  instead of builtinToolTypes.ts
- Update ChatPromptContext to use tools: InternalToolInfo[] instead of
  mcpTools + includeXMLToolDefinitions
- Update sendLLMMessageService.ts and convertToLLMMessageService.ts to
  import availableTools from browser/tools/toolRegistry.ts
@davi0015
davi0015 merged commit be9b4f9 into main Jul 9, 2026
MXZZ added a commit to MXZZ/working-void-editor that referenced this pull request Jul 9, 2026
Feature/tool restructuring (davi0015#83)
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.

1 participant