Support define is tool logic function (#17926)
- supports isTool and timeout settings in defineLogicFunction in apps and in setting tabs definition - compute for all toolInputSchema for logic funciton, in settings and in code steps <img width="991" height="802" alt="image" src="https://github.com/user-attachments/assets/05dc1221-cac9-45a3-87b0-3b13161446fd" />
This commit is contained in:
+3
-1
@@ -1,5 +1,7 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { DEFAULT_TOOL_INPUT_SCHEMA } from 'twenty-shared/logic-function';
|
||||
|
||||
import { MCP_SERVER_METADATA } from 'src/engine/api/mcp/constants/mcp.const';
|
||||
import { McpCoreController } from 'src/engine/api/mcp/controllers/mcp-core.controller';
|
||||
import { type JsonRpc } from 'src/engine/api/mcp/dtos/json-rpc';
|
||||
@@ -152,7 +154,7 @@ describe('McpCoreController', () => {
|
||||
{
|
||||
name: 'testTool',
|
||||
description: 'A test tool',
|
||||
inputSchema: { type: 'object', properties: {} },
|
||||
inputSchema: DEFAULT_TOOL_INPUT_SCHEMA,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
+6
-4
@@ -3,6 +3,8 @@ import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { jsonSchema } from 'ai';
|
||||
import { type JSONSchema7 } from 'json-schema';
|
||||
import { DEFAULT_TOOL_INPUT_SCHEMA } from 'twenty-shared/logic-function';
|
||||
|
||||
import { MCP_SERVER_METADATA } from 'src/engine/api/mcp/constants/mcp.const';
|
||||
import { type JsonRpc } from 'src/engine/api/mcp/dtos/json-rpc';
|
||||
@@ -264,7 +266,7 @@ describe('McpProtocolService', () => {
|
||||
|
||||
const mockTool = {
|
||||
description: 'Test tool',
|
||||
inputSchema: jsonSchema({ type: 'object', properties: {} }),
|
||||
inputSchema: jsonSchema(DEFAULT_TOOL_INPUT_SCHEMA as JSONSchema7),
|
||||
execute: jest.fn().mockResolvedValue({ result: 'success' }),
|
||||
};
|
||||
|
||||
@@ -319,7 +321,7 @@ describe('McpProtocolService', () => {
|
||||
|
||||
const mockTool = {
|
||||
description: 'Test tool',
|
||||
inputSchema: jsonSchema({ type: 'object', properties: {} }),
|
||||
inputSchema: jsonSchema(DEFAULT_TOOL_INPUT_SCHEMA as JSONSchema7),
|
||||
execute: jest.fn().mockResolvedValue({ result: 'success' }),
|
||||
};
|
||||
|
||||
@@ -375,7 +377,7 @@ describe('McpProtocolService', () => {
|
||||
const mockToolsMap = {
|
||||
testTool: {
|
||||
description: 'Test tool',
|
||||
inputSchema: jsonSchema({ type: 'object', properties: {} }),
|
||||
inputSchema: jsonSchema(DEFAULT_TOOL_INPUT_SCHEMA as JSONSchema7),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -393,7 +395,7 @@ describe('McpProtocolService', () => {
|
||||
{
|
||||
name: 'testTool',
|
||||
description: 'Test tool',
|
||||
inputSchema: { type: 'object', properties: {} },
|
||||
inputSchema: DEFAULT_TOOL_INPUT_SCHEMA,
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ export const fromLogicFunctionManifestToUniversalFlatLogicFunction = ({
|
||||
builtHandlerPath: logicFunctionManifest.builtHandlerPath,
|
||||
handlerName: logicFunctionManifest.handlerName,
|
||||
checksum: logicFunctionManifest.builtHandlerChecksum,
|
||||
toolInputSchema: logicFunctionManifest.toolInputSchema ?? null,
|
||||
toolInputSchema: logicFunctionManifest.toolInputSchema,
|
||||
isTool: logicFunctionManifest.isTool ?? false,
|
||||
cronTriggerSettings: logicFunctionManifest.cronTriggerSettings ?? null,
|
||||
databaseEventTriggerSettings:
|
||||
|
||||
-4
@@ -1,4 +0,0 @@
|
||||
export const SEED_LOGIC_FUNCTION_INPUT_SCHEMA = {
|
||||
a: null,
|
||||
b: null,
|
||||
};
|
||||
+4
-4
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { DEFAULT_TOOL_INPUT_SCHEMA } from 'twenty-shared/logic-function';
|
||||
|
||||
import {
|
||||
type GenerateDescriptorOptions,
|
||||
@@ -68,10 +69,9 @@ export class LogicFunctionToolProvider implements ToolProvider {
|
||||
|
||||
if (includeSchemas) {
|
||||
// Logic functions already store JSON Schema -- use it directly
|
||||
const inputSchema = (logicFunction.toolInputSchema as object) ?? {
|
||||
type: 'object',
|
||||
properties: {},
|
||||
};
|
||||
const inputSchema =
|
||||
(logicFunction.toolInputSchema as object) ??
|
||||
DEFAULT_TOOL_INPUT_SCHEMA;
|
||||
|
||||
descriptors.push({ ...base, inputSchema });
|
||||
} else {
|
||||
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
export const DEFAULT_TOOL_INPUT_SCHEMA = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
a: { type: 'string' },
|
||||
b: { type: 'number' },
|
||||
},
|
||||
};
|
||||
+3
-1
@@ -18,6 +18,8 @@ import {
|
||||
HttpRouteTriggerSettings,
|
||||
} from 'twenty-shared/application';
|
||||
|
||||
import type { InputJsonSchema } from 'twenty-shared/logic-function';
|
||||
|
||||
import type { JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type';
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
|
||||
@@ -52,7 +54,7 @@ export class CreateLogicFunction {
|
||||
|
||||
@Field(() => graphqlTypeJson, { nullable: false })
|
||||
@IsObject()
|
||||
toolInputSchema: object;
|
||||
toolInputSchema: InputJsonSchema;
|
||||
|
||||
@IsBoolean()
|
||||
@Field({ nullable: true })
|
||||
|
||||
+3
-1
@@ -22,6 +22,8 @@ import {
|
||||
HttpRouteTriggerSettings,
|
||||
} from 'twenty-shared/application';
|
||||
|
||||
import type { InputJsonSchema } from 'twenty-shared/logic-function';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
|
||||
@ObjectType('LogicFunction')
|
||||
@@ -69,7 +71,7 @@ export class LogicFunctionDTO {
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
toolInputSchema?: object;
|
||||
toolInputSchema?: InputJsonSchema;
|
||||
|
||||
@IsBoolean()
|
||||
@Field()
|
||||
|
||||
+2
-1
@@ -13,6 +13,7 @@ import {
|
||||
DatabaseEventTriggerSettings,
|
||||
HttpRouteTriggerSettings,
|
||||
} from 'twenty-shared/application';
|
||||
import { type InputJsonSchema } from 'twenty-shared/logic-function';
|
||||
|
||||
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
|
||||
import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type';
|
||||
@@ -59,7 +60,7 @@ export class LogicFunctionEntity
|
||||
checksum: string | null;
|
||||
|
||||
@Column({ nullable: true, type: 'jsonb' })
|
||||
toolInputSchema: JsonbProperty<object> | null;
|
||||
toolInputSchema: JsonbProperty<InputJsonSchema> | null;
|
||||
|
||||
@Column({ nullable: false, default: false })
|
||||
isTool: boolean;
|
||||
|
||||
+1
-1
@@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { join } from 'path';
|
||||
|
||||
import { v4 } from 'uuid';
|
||||
import { SEED_LOGIC_FUNCTION_INPUT_SCHEMA } from 'twenty-shared/logic-function';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/services/application.service';
|
||||
import { LogicFunctionExecutorService } from 'src/engine/core-modules/logic-function/logic-function-executor/logic-function-executor.service';
|
||||
@@ -14,7 +15,6 @@ import { LogicFunctionMetadataService } from 'src/engine/metadata-modules/logic-
|
||||
import { findFlatLogicFunctionOrThrow } from 'src/engine/metadata-modules/logic-function/utils/find-flat-logic-function-or-throw.util';
|
||||
import { fromFlatLogicFunctionToLogicFunctionDto } from 'src/engine/metadata-modules/logic-function/utils/from-flat-logic-function-to-logic-function-dto.util';
|
||||
import { CreateLogicFunctionFromSourceInput } from 'src/engine/metadata-modules/logic-function/dtos/create-logic-function-from-source.input';
|
||||
import { SEED_LOGIC_FUNCTION_INPUT_SCHEMA } from 'src/engine/core-modules/logic-function/logic-function-resource/constants/seed-logic-function-input-schema';
|
||||
import { UpdateLogicFunctionFromSourceInput } from 'src/engine/metadata-modules/logic-function/dtos/update-logic-function-from-source.input';
|
||||
import { getLogicFunctionSubfolderForFromSource } from 'src/engine/metadata-modules/logic-function/utils/get-logic-function-subfolder-for-from-source';
|
||||
import {
|
||||
|
||||
+4
-1
@@ -54,6 +54,9 @@ export class UpdateLogicFunctionActionHandlerService extends WorkspaceMigrationR
|
||||
LogicFunctionEntity,
|
||||
);
|
||||
|
||||
await logicFunctionRepository.update({ id: entityId, workspaceId }, update);
|
||||
await logicFunctionRepository.update(
|
||||
{ id: entityId, workspaceId },
|
||||
update as Parameters<typeof logicFunctionRepository.update>[1],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user