Skip to content

Commit bb5f294

Browse files
authored
[AI] Collapse NativeToolBinder to a single bind() entry (#20051)
The binder doesnt need an agent or full tool context -- just a model and options. Single `bind(model, options)` entry! Builds on #20022.
1 parent 13aaea5 commit bb5f294

6 files changed

Lines changed: 13 additions & 44 deletions

File tree

packages/twenty-server/src/engine/core-modules/tool-provider/interfaces/tool-provider-context.type.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { type ActorMetadata } from 'twenty-shared/types';
22

33
import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type';
44
import { type CodeExecutionStreamEmitter } from 'src/engine/core-modules/tool-provider/interfaces/code-execution-stream-emitter.type';
5-
import { type FlatAgentWithRoleId } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type';
65
import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config';
76

87
export type ToolProviderContext = {
@@ -13,6 +12,5 @@ export type ToolProviderContext = {
1312
actorContext?: ActorMetadata;
1413
userId?: string;
1514
userWorkspaceId?: string;
16-
agent?: FlatAgentWithRoleId | null;
1715
onCodeExecutionUpdate?: CodeExecutionStreamEmitter;
1816
};
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { type ToolSet } from 'ai';
22

3-
import { type ToolProviderContext } from 'src/engine/core-modules/tool-provider/interfaces/tool-provider-context.type';
3+
import { type RegisteredAiModel } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
4+
import { type NativeModelToolOptions } from 'src/engine/metadata-modules/ai/ai-models/types/native-model-tool-options.type';
45

56
// Parallel to ToolProvider, not a variant of it. A binder produces SDK-native
67
// tool objects (Anthropic webSearch, OpenAI webSearch, etc.) that the AI SDK
@@ -9,5 +10,5 @@ import { type ToolProviderContext } from 'src/engine/core-modules/tool-provider/
910
// executed by ToolExecutorService. They're merged directly into the ToolSet
1011
// handed to streamText.
1112
export interface NativeToolBinder {
12-
bind(context: ToolProviderContext): Promise<ToolSet>;
13+
bind(model: RegisteredAiModel, options: NativeModelToolOptions): ToolSet;
1314
}

packages/twenty-server/src/engine/core-modules/tool-provider/native/native-tool-binder.service.ts

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,16 @@ import { Injectable } from '@nestjs/common';
33
import { type ToolSet } from 'ai';
44

55
import { type NativeToolBinder } from 'src/engine/core-modules/tool-provider/native/native-tool-binder.interface';
6-
import { type ToolProviderContext } from 'src/engine/core-modules/tool-provider/interfaces/tool-provider-context.type';
76

87
import { AiModelConfigService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-config.service';
9-
import {
10-
AiModelRegistryService,
11-
type RegisteredAiModel,
12-
} from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
8+
import { type RegisteredAiModel } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
139
import { type NativeModelToolOptions } from 'src/engine/metadata-modules/ai/ai-models/types/native-model-tool-options.type';
1410

1511
@Injectable()
1612
export class NativeToolBinderService implements NativeToolBinder {
17-
constructor(
18-
private readonly aiModelConfigService: AiModelConfigService,
19-
private readonly aiModelRegistryService: AiModelRegistryService,
20-
) {}
13+
constructor(private readonly aiModelConfigService: AiModelConfigService) {}
2114

22-
async bind(context: ToolProviderContext): Promise<ToolSet> {
23-
if (!context.agent) {
24-
return {};
25-
}
26-
27-
const registeredModel =
28-
await this.aiModelRegistryService.resolveModelForAgent(context.agent);
29-
30-
return this.aiModelConfigService.getNativeModelToolsForAgent(
31-
registeredModel,
32-
context.agent,
33-
);
34-
}
35-
36-
bindForModel(
15+
bind(
3716
model: RegisteredAiModel,
3817
options: NativeModelToolOptions = {},
3918
): ToolSet {

packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-execution/services/agent-async-executor.service.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ export class AgentAsyncExecutorService {
150150
rolePermissionConfig: effectiveRoleConfig ?? { unionOf: [] },
151151
authContext,
152152
actorContext,
153-
agent: agent as unknown as ToolProviderContext['agent'],
154153
userId:
155154
isDefined(authContext) && isUserAuthContext(authContext)
156155
? authContext.user.id
@@ -169,8 +168,10 @@ export class AgentAsyncExecutorService {
169168
},
170169
);
171170

172-
const nativeTools =
173-
await this.nativeToolBinder.bind(toolProviderContext);
171+
const nativeTools = this.nativeToolBinder.bind(registeredModel, {
172+
webSearchEnabled:
173+
agent.modelConfiguration?.webSearch?.enabled === true,
174+
});
174175

175176
tools = {
176177
...registryTools,

packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/services/chat-execution.service.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,9 @@ export class ChatExecutionService {
157157
registeredModel.modelId,
158158
);
159159

160-
const nativeModelTools = this.nativeToolBinder.bindForModel(
161-
registeredModel,
162-
{ webSearchEnabled: true },
163-
);
160+
const nativeModelTools = this.nativeToolBinder.bind(registeredModel, {
161+
webSearchEnabled: true,
162+
});
164163

165164
// Tools the model can call directly: preloaded registry tools (already
166165
// serialized by the hydrator) plus SDK-native tools (opaque, never

packages/twenty-server/src/engine/metadata-modules/ai/ai-models/services/ai-model-config.service.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,6 @@ export class AiModelConfigService {
7979
return tools;
8080
}
8181

82-
getNativeModelToolsForAgent(
83-
model: RegisteredAiModel,
84-
agent: FlatAgentWithRoleId,
85-
): ToolSet {
86-
return this.getNativeModelTools(model, {
87-
webSearchEnabled: agent.modelConfiguration?.webSearch?.enabled === true,
88-
});
89-
}
90-
9182
private getXaiProviderOptions(agent: FlatAgentWithRoleId): ProviderOptions {
9283
if (
9384
!agent.modelConfiguration ||

0 commit comments

Comments
 (0)