Files
twenty/packages/twenty-server/src
Félix Malfait b77c44fd20 refactor(tool-provider): dedupe descriptor/generator paths (#19960)
## Summary

- Every tool provider used to implement `generateDescriptors()` **and**
register a category generator at `onModuleInit()` that re-ran the same
factories at execute time. `ToolExecutorService` carried two registries
(`staticToolHandlers`, `categoryGenerators`) to route between them.
- Providers now own execution of their own tools via a new
`executeStaticTool()` method. `ToolExecutorService` drops both maps and
delegates by `descriptor.category`. Each factory-backed provider has a
single `buildToolSet()` used by both descriptor generation and
execution.
- Extracts `resolveObjectIcon` shared util (was duplicated verbatim in
workflow + dashboard providers), and deletes the orphaned
`ToolGeneratorModule` whose consumers were removed in the earlier AI
chat simplification refactor.

No behavior change. Same factories run, same permission checks, same
tools execute. Net diff: 18 files, +311 / −480.

## Key changes

- `ToolProvider` interface gains `executeStaticTool(name, args,
context)`.
- `ToolExecutorService` loses its `staticToolHandlers` and
`categoryGenerators` maps, injects `TOOL_PROVIDERS`, and does
`providers.find(p => p.category ===
descriptor.category).executeStaticTool(...)` for `kind: 'static'`
descriptors.
- `ActionToolProvider` drops the register-handler loop in its
constructor; `executeStaticTool` looks up in the existing `toolMap`.
- `View`, `Metadata`, `Workflow`, `Dashboard`, `ViewField` providers
each have a single `buildToolSet(context)` private method used by both
`generateDescriptors` and `executeStaticTool`. No more `onModuleInit`,
no `ToolExecutorService` dependency.
- `DatabaseToolProvider` and `LogicFunctionToolProvider` implement
`executeStaticTool` with an invariant-violation throw — they only emit
`database_crud` / `logic_function` kinds, so the static-tool path is
unreachable for them.
- Deletes `tool-generator/` (dead code — zero consumers).

## Dependency graph before/after

**Before:** provider → `ToolExecutorService` (for `register*` calls)
**After:** `ToolExecutorService` → `TOOL_PROVIDERS` → providers.
Cleaner, no cycle.

## Test plan

- [ ] `npx nx typecheck twenty-server` passes (verified: same 7
pre-existing unrelated errors)
- [ ] `npx nx lint twenty-server` passes
- [ ] AI chat: trigger a tool call that hits `execute_tool` fallback
(e.g. a view/metadata tool not in the preloaded set) — verify it still
executes
- [ ] AI chat: trigger a preloaded action tool (e.g.
`search_help_center`) — verify it still executes
- [ ] MCP: `tools/list` and `tools/call` for both preloaded and
catalog-discovered tools
- [ ] Workflow AI agent: run a workflow with AI agent step that calls
DATABASE_CRUD tools
- [ ] Verify the `web_search` / `code_interpreter` tools (if enabled)
still dispatch correctly

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:32:03 +02:00
..
2025-11-18 13:55:34 +01:00
2026-04-21 13:47:19 +02:00
2026-01-23 15:38:15 +00:00