[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.
This commit is contained in:
-2
@@ -2,7 +2,6 @@ import { type ActorMetadata } from 'twenty-shared/types';
|
||||
|
||||
import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type';
|
||||
import { type CodeExecutionStreamEmitter } from 'src/engine/core-modules/tool-provider/interfaces/code-execution-stream-emitter.type';
|
||||
import { type FlatAgentWithRoleId } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type';
|
||||
import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config';
|
||||
|
||||
export type ToolProviderContext = {
|
||||
@@ -13,6 +12,5 @@ export type ToolProviderContext = {
|
||||
actorContext?: ActorMetadata;
|
||||
userId?: string;
|
||||
userWorkspaceId?: string;
|
||||
agent?: FlatAgentWithRoleId | null;
|
||||
onCodeExecutionUpdate?: CodeExecutionStreamEmitter;
|
||||
};
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
import { type ToolSet } from 'ai';
|
||||
|
||||
import { type ToolProviderContext } from 'src/engine/core-modules/tool-provider/interfaces/tool-provider-context.type';
|
||||
import { type RegisteredAiModel } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
|
||||
import { type NativeModelToolOptions } from 'src/engine/metadata-modules/ai/ai-models/types/native-model-tool-options.type';
|
||||
|
||||
// Parallel to ToolProvider, not a variant of it. A binder produces SDK-native
|
||||
// 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/
|
||||
// executed by ToolExecutorService. They're merged directly into the ToolSet
|
||||
// handed to streamText.
|
||||
export interface NativeToolBinder {
|
||||
bind(context: ToolProviderContext): Promise<ToolSet>;
|
||||
bind(model: RegisteredAiModel, options: NativeModelToolOptions): ToolSet;
|
||||
}
|
||||
|
||||
+3
-24
@@ -3,37 +3,16 @@ import { Injectable } from '@nestjs/common';
|
||||
import { type ToolSet } from 'ai';
|
||||
|
||||
import { type NativeToolBinder } from 'src/engine/core-modules/tool-provider/native/native-tool-binder.interface';
|
||||
import { type ToolProviderContext } from 'src/engine/core-modules/tool-provider/interfaces/tool-provider-context.type';
|
||||
|
||||
import { AiModelConfigService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-config.service';
|
||||
import {
|
||||
AiModelRegistryService,
|
||||
type RegisteredAiModel,
|
||||
} from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
|
||||
import { type RegisteredAiModel } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
|
||||
import { type NativeModelToolOptions } from 'src/engine/metadata-modules/ai/ai-models/types/native-model-tool-options.type';
|
||||
|
||||
@Injectable()
|
||||
export class NativeToolBinderService implements NativeToolBinder {
|
||||
constructor(
|
||||
private readonly aiModelConfigService: AiModelConfigService,
|
||||
private readonly aiModelRegistryService: AiModelRegistryService,
|
||||
) {}
|
||||
constructor(private readonly aiModelConfigService: AiModelConfigService) {}
|
||||
|
||||
async bind(context: ToolProviderContext): Promise<ToolSet> {
|
||||
if (!context.agent) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const registeredModel =
|
||||
await this.aiModelRegistryService.resolveModelForAgent(context.agent);
|
||||
|
||||
return this.aiModelConfigService.getNativeModelToolsForAgent(
|
||||
registeredModel,
|
||||
context.agent,
|
||||
);
|
||||
}
|
||||
|
||||
bindForModel(
|
||||
bind(
|
||||
model: RegisteredAiModel,
|
||||
options: NativeModelToolOptions = {},
|
||||
): ToolSet {
|
||||
|
||||
+4
-3
@@ -150,7 +150,6 @@ export class AgentAsyncExecutorService {
|
||||
rolePermissionConfig: effectiveRoleConfig ?? { unionOf: [] },
|
||||
authContext,
|
||||
actorContext,
|
||||
agent: agent as unknown as ToolProviderContext['agent'],
|
||||
userId:
|
||||
isDefined(authContext) && isUserAuthContext(authContext)
|
||||
? authContext.user.id
|
||||
@@ -169,8 +168,10 @@ export class AgentAsyncExecutorService {
|
||||
},
|
||||
);
|
||||
|
||||
const nativeTools =
|
||||
await this.nativeToolBinder.bind(toolProviderContext);
|
||||
const nativeTools = this.nativeToolBinder.bind(registeredModel, {
|
||||
webSearchEnabled:
|
||||
agent.modelConfiguration?.webSearch?.enabled === true,
|
||||
});
|
||||
|
||||
tools = {
|
||||
...registryTools,
|
||||
|
||||
+3
-4
@@ -157,10 +157,9 @@ export class ChatExecutionService {
|
||||
registeredModel.modelId,
|
||||
);
|
||||
|
||||
const nativeModelTools = this.nativeToolBinder.bindForModel(
|
||||
registeredModel,
|
||||
{ webSearchEnabled: true },
|
||||
);
|
||||
const nativeModelTools = this.nativeToolBinder.bind(registeredModel, {
|
||||
webSearchEnabled: true,
|
||||
});
|
||||
|
||||
// Tools the model can call directly: preloaded registry tools (already
|
||||
// serialized by the hydrator) plus SDK-native tools (opaque, never
|
||||
|
||||
-9
@@ -79,15 +79,6 @@ export class AiModelConfigService {
|
||||
return tools;
|
||||
}
|
||||
|
||||
getNativeModelToolsForAgent(
|
||||
model: RegisteredAiModel,
|
||||
agent: FlatAgentWithRoleId,
|
||||
): ToolSet {
|
||||
return this.getNativeModelTools(model, {
|
||||
webSearchEnabled: agent.modelConfiguration?.webSearch?.enabled === true,
|
||||
});
|
||||
}
|
||||
|
||||
private getXaiProviderOptions(agent: FlatAgentWithRoleId): ProviderOptions {
|
||||
if (
|
||||
!agent.modelConfiguration ||
|
||||
|
||||
Reference in New Issue
Block a user