Files
twenty/packages
Abdul Rahman ea7863dc4e feat(ai-agent): lazy tool loading for the open-ended runAgent path (#23454)
## Context

`AgentAsyncExecutorService.executeAgent` is shared by workflow agent
nodes and the `runAgent` mutation (Slack assistant, apps). Workflow
nodes run a scoped task, so pre-loading the few explicitly-granted
object tools is fast and skips
the `learn_tools` round trip (the behavior settled in #23400 / #23358).
`runAgent` is open-ended: its role grants broad object access, so
pre-loading inlines every CRUD/action schema on every step. That is what
makes the Slack assistant take 3-4 minutes for a prompt Ask AI answers
in seconds. Confirmed still slow with #23400 merged, so this is the
payload, not object scoping.

## What

Add a `toolLoadingStrategy` to `executeAgent` (default `'preload'`, so
workflow nodes and evals are unchanged). `AgentRunService.run` opts into
`'lazy'`, which exposes a compact tool catalog in the system prompt plus
the `learn_tools` / `execute_tool` meta-tools, using composed role
permissions rather than explicit grants only, so the agent keeps broad
access without the full-payload latency.

## How

- Split tool provisioning into two focused methods on the executor; a
3-line dispatch chooses per strategy. The pre-load path is unchanged.
- `buildLazyRegistryToolset`: one reusable definition of lazy registry
provisioning (catalog + meta-tools), so the chat and agent executors can
share it.
- Extract `buildToolCatalogSection` out of `SystemPromptBuilderService`
into a `tool-provider` util so both paths format the catalog identically
(no dup).
- Replace the meta-tools' `excludeTools` denylist with a single
`isToolAllowed` predicate: the agent path passes an allowlist closed
over the shown catalog (enforced at call time), MCP passes its existing
deny predicate.

Workflow node and eval behavior is unchanged.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23454?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-29 12:15:56 +00:00
..