feat(apps): split AI tool and workflow action triggers in LogicFunction manifest (#20208)
## Summary Replaces the bolted-on `isTool` + `toolInputSchema` fields on `LogicFunctionManifest` with two distinct, opt-in triggers that align with the existing `cron` / `databaseEvent` / `httpRoute` trigger pattern: - **`toolTriggerSettings`** — exposes the function as an AI tool (chat / MCP / function calling). Uses standard JSON Schema (the format LLMs natively understand). - **`workflowActionTriggerSettings`** — exposes the function as a step in the visual workflow builder. Uses Twenty's rich `InputSchema` so the builder can render proper `FieldMetadataType`-aware editors, variable pickers, labels, and an optional `outputSchema`. A function can opt into none, one, or both. Each surface gets the schema format appropriate for it. ### Why `isTool: true` previously exposed the function as both an AI tool AND a workflow node, with the same JSON Schema feeding both — but the workflow builder really wants Twenty's `InputSchema` (with `CURRENCY`, `RELATION`, `EMAILS`, etc.) and the AI surface really wants standard JSON Schema. Today the workflow builder hacks around this by treating JSON Schema as `InputSchema`, which silently breaks for any non-primitive field type. Splitting the triggers fixes that and lets each surface evolve independently. ### Migration - **Fast** instance command adds the two new nullable columns. - **Slow** instance command backfills `toolTriggerSettings` + `workflowActionTriggerSettings` from `isTool=true` rows (preserving today's both-surfaces behaviour) then drops the legacy columns. ### Stacked Stacked on top of #20181. Merge that first, then this. ## Test plan - [ ] CI green (oxlint, typecheck, jest, vitest) - [ ] Run `--include-slow` upgrade against a workspace with existing `isTool=true` logic functions; verify both new columns populated and old columns dropped - [ ] Verify AI chat sees migrated tool functions (Linear create-issue, Exa search) and can call them with the JSON Schema - [ ] Add an AI-tool function from the Settings UI (toggles `toolTriggerSettings`) and verify it shows up in chat - [ ] Add a workflow-action function from the Settings UI (toggles `workflowActionTriggerSettings`) and verify it appears in the workflow node picker - [ ] In the workflow builder, edit a `LOGIC_FUNCTION` step and verify input fields render (no more JSON-Schema-as-InputSchema hack) - [ ] Try defining a function with no triggers in the SDK and verify `defineLogicFunction` rejects it 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: martmull <martmull@hotmail.fr>
This commit is contained in:
+3
-2
@@ -28,13 +28,14 @@ export const fromLogicFunctionManifestToUniversalFlatLogicFunction = ({
|
||||
builtHandlerPath: logicFunctionManifest.builtHandlerPath,
|
||||
handlerName: logicFunctionManifest.handlerName,
|
||||
checksum: logicFunctionManifest.builtHandlerChecksum,
|
||||
toolInputSchema: logicFunctionManifest.toolInputSchema,
|
||||
isTool: logicFunctionManifest.isTool ?? false,
|
||||
cronTriggerSettings: logicFunctionManifest.cronTriggerSettings ?? null,
|
||||
databaseEventTriggerSettings:
|
||||
logicFunctionManifest.databaseEventTriggerSettings ?? null,
|
||||
httpRouteTriggerSettings:
|
||||
logicFunctionManifest.httpRouteTriggerSettings ?? null,
|
||||
toolTriggerSettings: logicFunctionManifest.toolTriggerSettings ?? null,
|
||||
workflowActionTriggerSettings:
|
||||
logicFunctionManifest.workflowActionTriggerSettings ?? null,
|
||||
isBuildUpToDate: true,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// Refresh result returned by the app OAuth driver. Mirrors
|
||||
// `ConnectedAccountTokens` from the central refresh manager but redeclared
|
||||
// here so this engine-side driver has zero dependency on `modules/`.
|
||||
|
||||
export type AppOAuthTokens = {
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
};
|
||||
+42
@@ -42,6 +42,48 @@ export class ApplicationVariableEntityService {
|
||||
});
|
||||
}
|
||||
|
||||
// Decrypted plaintext value. Server-side only — never expose via GraphQL.
|
||||
// Used by trusted server flows that need the raw secret (e.g. exchanging an
|
||||
// OAuth client secret with a third-party provider).
|
||||
getRawValue(applicationVariable: ApplicationVariableEntity): string {
|
||||
if (!applicationVariable.isSecret) {
|
||||
return applicationVariable.value;
|
||||
}
|
||||
|
||||
return this.secretEncryptionService.decrypt(applicationVariable.value);
|
||||
}
|
||||
|
||||
async findOneByKey({
|
||||
applicationId,
|
||||
key,
|
||||
}: {
|
||||
applicationId: string;
|
||||
key: string;
|
||||
}): Promise<ApplicationVariableEntity | null> {
|
||||
return this.applicationVariableRepository.findOne({
|
||||
where: { applicationId, key },
|
||||
});
|
||||
}
|
||||
|
||||
async getRawValueByKeyOrThrow({
|
||||
applicationId,
|
||||
key,
|
||||
}: {
|
||||
applicationId: string;
|
||||
key: string;
|
||||
}): Promise<string> {
|
||||
const variable = await this.findOneByKey({ applicationId, key });
|
||||
|
||||
if (!isDefined(variable)) {
|
||||
throw new ApplicationVariableEntityException(
|
||||
`Application variable "${key}" not found for application ${applicationId}`,
|
||||
ApplicationVariableEntityExceptionCode.APPLICATION_VARIABLE_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return this.getRawValue(variable);
|
||||
}
|
||||
|
||||
async update({
|
||||
key,
|
||||
plainTextValue,
|
||||
|
||||
+9
-7
@@ -58,7 +58,9 @@ export class LogicFunctionToolProvider implements ToolProvider {
|
||||
flatLogicFunctionMaps.byUniversalIdentifier,
|
||||
).filter(
|
||||
(fn): fn is FlatLogicFunction =>
|
||||
isDefined(fn) && fn.isTool === true && fn.deletedAt === null,
|
||||
isDefined(fn) &&
|
||||
isDefined(fn.toolTriggerSettings) &&
|
||||
fn.deletedAt === null,
|
||||
);
|
||||
|
||||
const descriptors: (ToolIndexEntry | ToolDescriptor)[] = [];
|
||||
@@ -79,12 +81,12 @@ export class LogicFunctionToolProvider implements ToolProvider {
|
||||
};
|
||||
|
||||
if (includeSchemas) {
|
||||
// Logic functions already store JSON Schema -- use it directly
|
||||
const inputSchema =
|
||||
(logicFunction.toolInputSchema as object) ??
|
||||
DEFAULT_TOOL_INPUT_SCHEMA;
|
||||
|
||||
descriptors.push({ ...base, inputSchema });
|
||||
descriptors.push({
|
||||
...base,
|
||||
inputSchema:
|
||||
(logicFunction.toolTriggerSettings?.inputSchema as object) ??
|
||||
DEFAULT_TOOL_INPUT_SCHEMA,
|
||||
});
|
||||
} else {
|
||||
descriptors.push(base);
|
||||
}
|
||||
|
||||
+4
-3
@@ -114,20 +114,21 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY should ma
|
||||
"checksum",
|
||||
"sourceHandlerPath",
|
||||
"handlerName",
|
||||
"toolInputSchema",
|
||||
"isTool",
|
||||
"isBuildUpToDate",
|
||||
"deletedAt",
|
||||
"cronTriggerSettings",
|
||||
"databaseEventTriggerSettings",
|
||||
"httpRouteTriggerSettings",
|
||||
"toolTriggerSettings",
|
||||
"workflowActionTriggerSettings",
|
||||
"builtHandlerPath",
|
||||
],
|
||||
"propertiesToStringify": [
|
||||
"toolInputSchema",
|
||||
"cronTriggerSettings",
|
||||
"databaseEventTriggerSettings",
|
||||
"httpRouteTriggerSettings",
|
||||
"toolTriggerSettings",
|
||||
"workflowActionTriggerSettings",
|
||||
],
|
||||
},
|
||||
"navigationMenuItem": {
|
||||
|
||||
+10
-10
@@ -576,16 +576,6 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
toolInputSchema: {
|
||||
toCompare: true,
|
||||
toStringify: true,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
isTool: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
isBuildUpToDate: {
|
||||
toCompare: true,
|
||||
toStringify: false,
|
||||
@@ -611,6 +601,16 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = {
|
||||
toStringify: true,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
toolTriggerSettings: {
|
||||
toCompare: true,
|
||||
toStringify: true,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
workflowActionTriggerSettings: {
|
||||
toCompare: true,
|
||||
toStringify: true,
|
||||
universalProperty: undefined,
|
||||
},
|
||||
createdAt: {
|
||||
toCompare: false,
|
||||
toStringify: false,
|
||||
|
||||
+2
-2
@@ -7,10 +7,10 @@ export const FLAT_LOGIC_FUNCTION_EDITABLE_PROPERTIES = [
|
||||
'checksum',
|
||||
'sourceHandlerPath',
|
||||
'handlerName',
|
||||
'toolInputSchema',
|
||||
'isTool',
|
||||
'cronTriggerSettings',
|
||||
'databaseEventTriggerSettings',
|
||||
'httpRouteTriggerSettings',
|
||||
'toolTriggerSettings',
|
||||
'workflowActionTriggerSettings',
|
||||
'isBuildUpToDate',
|
||||
] as const satisfies MetadataEntityPropertyName<'logicFunction'>[];
|
||||
|
||||
+12
-11
@@ -1,7 +1,6 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import {
|
||||
IsBoolean,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsObject,
|
||||
@@ -16,6 +15,8 @@ import {
|
||||
CronTriggerSettings,
|
||||
DatabaseEventTriggerSettings,
|
||||
HttpRouteTriggerSettings,
|
||||
ToolTriggerSettings,
|
||||
WorkflowActionTriggerSettings,
|
||||
} from 'twenty-shared/application';
|
||||
|
||||
import type { JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type';
|
||||
@@ -51,16 +52,6 @@ export class CreateLogicFunctionFromSourceInput {
|
||||
@IsOptional()
|
||||
timeoutSeconds?: number;
|
||||
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
toolInputSchema?: object;
|
||||
|
||||
@IsBoolean()
|
||||
@Field({ nullable: true })
|
||||
@IsOptional()
|
||||
isTool?: boolean;
|
||||
|
||||
@IsObject()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsOptional()
|
||||
@@ -80,4 +71,14 @@ export class CreateLogicFunctionFromSourceInput {
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsOptional()
|
||||
httpRouteTriggerSettings?: JsonbProperty<HttpRouteTriggerSettings>;
|
||||
|
||||
@IsObject()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsOptional()
|
||||
toolTriggerSettings?: JsonbProperty<ToolTriggerSettings>;
|
||||
|
||||
@IsObject()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsOptional()
|
||||
workflowActionTriggerSettings?: JsonbProperty<WorkflowActionTriggerSettings>;
|
||||
}
|
||||
|
||||
+1
-6
@@ -1,7 +1,6 @@
|
||||
import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import { IsObject, IsString, Matches } from 'class-validator';
|
||||
import graphqlTypeJson from 'graphql-type-json';
|
||||
import { IsString, Matches } from 'class-validator';
|
||||
|
||||
import { HANDLER_NAME_REGEX } from 'src/engine/metadata-modules/logic-function/constants/handler.contant';
|
||||
|
||||
@@ -11,10 +10,6 @@ export class LogicFunctionSourceInput {
|
||||
@Field({ nullable: false })
|
||||
sourceHandlerCode: string;
|
||||
|
||||
@Field(() => graphqlTypeJson, { nullable: false })
|
||||
@IsObject()
|
||||
toolInputSchema: object;
|
||||
|
||||
@IsString()
|
||||
@Matches(HANDLER_NAME_REGEX, {
|
||||
message: 'handlerName must be a valid JavaScript identifier or dotted path',
|
||||
|
||||
+12
-12
@@ -6,7 +6,6 @@ import {
|
||||
QueryOptions,
|
||||
} from '@ptc-org/nestjs-query-graphql';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsDateString,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
@@ -20,10 +19,10 @@ import {
|
||||
CronTriggerSettings,
|
||||
DatabaseEventTriggerSettings,
|
||||
HttpRouteTriggerSettings,
|
||||
ToolTriggerSettings,
|
||||
WorkflowActionTriggerSettings,
|
||||
} 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')
|
||||
@@ -68,15 +67,6 @@ export class LogicFunctionDTO {
|
||||
@Field()
|
||||
handlerName: string;
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
toolInputSchema?: InputJsonSchema;
|
||||
|
||||
@IsBoolean()
|
||||
@Field()
|
||||
isTool: boolean;
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@@ -92,6 +82,16 @@ export class LogicFunctionDTO {
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
httpRouteTriggerSettings?: HttpRouteTriggerSettings;
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
toolTriggerSettings?: ToolTriggerSettings;
|
||||
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
workflowActionTriggerSettings?: WorkflowActionTriggerSettings;
|
||||
|
||||
@IsUUID()
|
||||
@IsOptional()
|
||||
@Field(() => UUIDScalarType, { nullable: true })
|
||||
|
||||
+12
-11
@@ -2,7 +2,6 @@ import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsObject,
|
||||
@@ -19,6 +18,8 @@ import {
|
||||
CronTriggerSettings,
|
||||
DatabaseEventTriggerSettings,
|
||||
HttpRouteTriggerSettings,
|
||||
ToolTriggerSettings,
|
||||
WorkflowActionTriggerSettings,
|
||||
} from 'twenty-shared/application';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
@@ -49,11 +50,6 @@ class UpdateLogicFunctionFromSourceInputUpdates {
|
||||
@IsOptional()
|
||||
sourceHandlerCode?: string;
|
||||
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsObject()
|
||||
@IsOptional()
|
||||
toolInputSchema?: object;
|
||||
|
||||
@IsString()
|
||||
@Matches(HANDLER_NAME_REGEX, {
|
||||
message: 'handlerName must be a valid JavaScript identifier or dotted path',
|
||||
@@ -67,11 +63,6 @@ class UpdateLogicFunctionFromSourceInputUpdates {
|
||||
@IsOptional()
|
||||
sourceHandlerPath?: string;
|
||||
|
||||
@IsBoolean()
|
||||
@Field({ nullable: true })
|
||||
@IsOptional()
|
||||
isTool?: boolean;
|
||||
|
||||
@IsObject()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsOptional()
|
||||
@@ -86,6 +77,16 @@ class UpdateLogicFunctionFromSourceInputUpdates {
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsOptional()
|
||||
httpRouteTriggerSettings?: JsonbProperty<HttpRouteTriggerSettings>;
|
||||
|
||||
@IsObject()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsOptional()
|
||||
toolTriggerSettings?: JsonbProperty<ToolTriggerSettings>;
|
||||
|
||||
@IsObject()
|
||||
@Field(() => graphqlTypeJson, { nullable: true })
|
||||
@IsOptional()
|
||||
workflowActionTriggerSettings?: JsonbProperty<WorkflowActionTriggerSettings>;
|
||||
}
|
||||
|
||||
@InputType()
|
||||
|
||||
+8
-7
@@ -12,8 +12,9 @@ import {
|
||||
CronTriggerSettings,
|
||||
DatabaseEventTriggerSettings,
|
||||
HttpRouteTriggerSettings,
|
||||
ToolTriggerSettings,
|
||||
WorkflowActionTriggerSettings,
|
||||
} 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,12 +60,6 @@ export class LogicFunctionEntity
|
||||
@Column({ nullable: true, type: 'text' })
|
||||
checksum: string | null;
|
||||
|
||||
@Column({ nullable: true, type: 'jsonb' })
|
||||
toolInputSchema: JsonbProperty<InputJsonSchema> | null;
|
||||
|
||||
@Column({ nullable: false, default: false })
|
||||
isTool: boolean;
|
||||
|
||||
@Column({ nullable: false, type: 'boolean', default: true })
|
||||
isBuildUpToDate: boolean;
|
||||
|
||||
@@ -77,6 +72,12 @@ export class LogicFunctionEntity
|
||||
@Column({ nullable: true, type: 'jsonb' })
|
||||
httpRouteTriggerSettings: JsonbProperty<HttpRouteTriggerSettings> | null;
|
||||
|
||||
@Column({ nullable: true, type: 'jsonb' })
|
||||
toolTriggerSettings: JsonbProperty<ToolTriggerSettings> | null;
|
||||
|
||||
@Column({ nullable: true, type: 'jsonb' })
|
||||
workflowActionTriggerSettings: JsonbProperty<WorkflowActionTriggerSettings> | null;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
+3
-5
@@ -4,7 +4,6 @@ import crypto from 'crypto';
|
||||
|
||||
import { v4 } from 'uuid';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { SEED_LOGIC_FUNCTION_INPUT_SCHEMA } from 'twenty-shared/logic-function';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
@@ -76,7 +75,6 @@ export class LogicFunctionFromSourceService {
|
||||
builtHandlerPath,
|
||||
handlerName: input.source.handlerName,
|
||||
checksum: null,
|
||||
toolInputSchema: input.source.toolInputSchema,
|
||||
isBuildUpToDate: false,
|
||||
applicationUniversalIdentifier:
|
||||
ownerFlatApplication.universalIdentifier,
|
||||
@@ -111,7 +109,6 @@ export class LogicFunctionFromSourceService {
|
||||
builtHandlerPath,
|
||||
handlerName,
|
||||
checksum,
|
||||
toolInputSchema: SEED_LOGIC_FUNCTION_INPUT_SCHEMA,
|
||||
isBuildUpToDate: true,
|
||||
applicationUniversalIdentifier:
|
||||
ownerFlatApplication.universalIdentifier,
|
||||
@@ -170,8 +167,6 @@ export class LogicFunctionFromSourceService {
|
||||
name: existingLogicFunction.name,
|
||||
description: existingLogicFunction.description,
|
||||
timeoutSeconds: existingLogicFunction.timeoutSeconds,
|
||||
toolInputSchema: existingLogicFunction.toolInputSchema,
|
||||
isTool: existingLogicFunction.isTool,
|
||||
isBuildUpToDate: existingLogicFunction.isBuildUpToDate,
|
||||
checksum: existingLogicFunction.checksum,
|
||||
handlerName: existingLogicFunction.handlerName,
|
||||
@@ -182,6 +177,9 @@ export class LogicFunctionFromSourceService {
|
||||
existingLogicFunction.databaseEventTriggerSettings,
|
||||
httpRouteTriggerSettings:
|
||||
existingLogicFunction.httpRouteTriggerSettings,
|
||||
toolTriggerSettings: existingLogicFunction.toolTriggerSettings,
|
||||
workflowActionTriggerSettings:
|
||||
existingLogicFunction.workflowActionTriggerSettings,
|
||||
applicationUniversalIdentifier:
|
||||
ownerFlatApplication.universalIdentifier,
|
||||
});
|
||||
|
||||
+2
-2
@@ -39,8 +39,6 @@ export const buildUniversalFlatLogicFunctionToCreate = (
|
||||
runtime: LogicFunctionRuntime.NODE22,
|
||||
timeoutSeconds: input.timeoutSeconds ?? 300,
|
||||
checksum: input.checksum ?? null,
|
||||
toolInputSchema: input.toolInputSchema ?? null,
|
||||
isTool: input.isTool ?? false,
|
||||
isBuildUpToDate: input.isBuildUpToDate,
|
||||
handlerName: input.handlerName,
|
||||
sourceHandlerPath: input.sourceHandlerPath,
|
||||
@@ -48,6 +46,8 @@ export const buildUniversalFlatLogicFunctionToCreate = (
|
||||
cronTriggerSettings: input.cronTriggerSettings ?? null,
|
||||
databaseEventTriggerSettings: input.databaseEventTriggerSettings ?? null,
|
||||
httpRouteTriggerSettings: input.httpRouteTriggerSettings ?? null,
|
||||
toolTriggerSettings: input.toolTriggerSettings ?? null,
|
||||
workflowActionTriggerSettings: input.workflowActionTriggerSettings ?? null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
deletedAt: null,
|
||||
|
||||
+5
-4
@@ -12,7 +12,6 @@ export const fromCreateLogicFunctionFromSourceInputToUniversalFlatLogicFunctionT
|
||||
builtHandlerPath,
|
||||
handlerName,
|
||||
checksum,
|
||||
toolInputSchema,
|
||||
isBuildUpToDate,
|
||||
applicationUniversalIdentifier,
|
||||
}: {
|
||||
@@ -21,7 +20,6 @@ export const fromCreateLogicFunctionFromSourceInputToUniversalFlatLogicFunctionT
|
||||
builtHandlerPath: string;
|
||||
handlerName: string;
|
||||
checksum: string | null;
|
||||
toolInputSchema: object | null;
|
||||
isBuildUpToDate: boolean;
|
||||
applicationUniversalIdentifier: string;
|
||||
}): UniversalFlatLogicFunction & { id: string } => {
|
||||
@@ -44,8 +42,6 @@ export const fromCreateLogicFunctionFromSourceInputToUniversalFlatLogicFunctionT
|
||||
runtime: LogicFunctionRuntime.NODE22,
|
||||
timeoutSeconds: createLogicFunctionFromSourceInput.timeoutSeconds ?? 300,
|
||||
checksum,
|
||||
toolInputSchema,
|
||||
isTool: createLogicFunctionFromSourceInput.isTool ?? false,
|
||||
isBuildUpToDate,
|
||||
handlerName,
|
||||
sourceHandlerPath,
|
||||
@@ -56,6 +52,11 @@ export const fromCreateLogicFunctionFromSourceInputToUniversalFlatLogicFunctionT
|
||||
createLogicFunctionFromSourceInput.databaseEventTriggerSettings ?? null,
|
||||
httpRouteTriggerSettings:
|
||||
createLogicFunctionFromSourceInput.httpRouteTriggerSettings ?? null,
|
||||
toolTriggerSettings:
|
||||
createLogicFunctionFromSourceInput.toolTriggerSettings ?? null,
|
||||
workflowActionTriggerSettings:
|
||||
createLogicFunctionFromSourceInput.workflowActionTriggerSettings ??
|
||||
null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
deletedAt: null,
|
||||
|
||||
+3
-2
@@ -15,8 +15,6 @@ export const fromFlatLogicFunctionToLogicFunctionDto = ({
|
||||
timeoutSeconds: flatLogicFunction.timeoutSeconds,
|
||||
sourceHandlerPath: flatLogicFunction.sourceHandlerPath,
|
||||
handlerName: flatLogicFunction.handlerName,
|
||||
toolInputSchema: flatLogicFunction.toolInputSchema ?? undefined,
|
||||
isTool: flatLogicFunction.isTool,
|
||||
applicationId: flatLogicFunction.applicationId ?? undefined,
|
||||
workspaceId: flatLogicFunction.workspaceId,
|
||||
createdAt: new Date(flatLogicFunction.createdAt),
|
||||
@@ -26,5 +24,8 @@ export const fromFlatLogicFunctionToLogicFunctionDto = ({
|
||||
flatLogicFunction.databaseEventTriggerSettings ?? undefined,
|
||||
httpRouteTriggerSettings:
|
||||
flatLogicFunction.httpRouteTriggerSettings ?? undefined,
|
||||
toolTriggerSettings: flatLogicFunction.toolTriggerSettings ?? undefined,
|
||||
workflowActionTriggerSettings:
|
||||
flatLogicFunction.workflowActionTriggerSettings ?? undefined,
|
||||
};
|
||||
};
|
||||
|
||||
-2
@@ -45,10 +45,8 @@ export class PrefillLogicFunctionService {
|
||||
id: definition.id,
|
||||
name: definition.name,
|
||||
description: definition.description,
|
||||
toolInputSchema: definition.toolInputSchema,
|
||||
source: {
|
||||
sourceHandlerCode: definition.sourceHandlerCode,
|
||||
toolInputSchema: definition.toolInputSchema,
|
||||
handlerName: 'main',
|
||||
},
|
||||
},
|
||||
|
||||
-40
@@ -20,42 +20,6 @@ export const getCreateCompanyWhenAddingNewPersonCodeStepLogicFunctionIds = (
|
||||
),
|
||||
});
|
||||
|
||||
const EXTRACT_DOMAIN_TOOL_INPUT_SCHEMA = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
email: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
required: ['email'],
|
||||
};
|
||||
|
||||
const IS_PERSONAL_EMAIL_TOOL_INPUT_SCHEMA = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
primaryEmail: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
required: ['primaryEmail'],
|
||||
};
|
||||
|
||||
const FIND_MATCHING_COMPANY_BY_DOMAIN_TOOL_INPUT_SCHEMA = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
companies: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
},
|
||||
},
|
||||
domain: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
required: ['companies', 'domain'],
|
||||
};
|
||||
|
||||
const EXTRACT_DOMAIN_LOGIC_FUNCTION_SOURCE = `const psl = require('psl');
|
||||
|
||||
export const main = async (params) => {
|
||||
@@ -184,7 +148,6 @@ export type PrefilledWorkflowCodeStepLogicFunctionDefinition = {
|
||||
name: string;
|
||||
description: string;
|
||||
sourceHandlerCode: string;
|
||||
toolInputSchema: object;
|
||||
};
|
||||
|
||||
export const getCreateCompanyWhenAddingNewPersonCodeStepLogicFunctionDefinitions =
|
||||
@@ -203,7 +166,6 @@ export const getCreateCompanyWhenAddingNewPersonCodeStepLogicFunctionDefinitions
|
||||
description:
|
||||
'Extracts a normalized company domain and URL from a person email address.',
|
||||
sourceHandlerCode: EXTRACT_DOMAIN_LOGIC_FUNCTION_SOURCE,
|
||||
toolInputSchema: EXTRACT_DOMAIN_TOOL_INPUT_SCHEMA,
|
||||
},
|
||||
{
|
||||
id: findMatchingCompanyByDomainLogicFunctionId,
|
||||
@@ -212,7 +174,6 @@ export const getCreateCompanyWhenAddingNewPersonCodeStepLogicFunctionDefinitions
|
||||
'Finds an existing company whose website matches a normalized registrable domain.',
|
||||
sourceHandlerCode:
|
||||
FIND_MATCHING_COMPANY_BY_DOMAIN_LOGIC_FUNCTION_SOURCE,
|
||||
toolInputSchema: FIND_MATCHING_COMPANY_BY_DOMAIN_TOOL_INPUT_SCHEMA,
|
||||
},
|
||||
{
|
||||
id: isPersonalEmailLogicFunctionId,
|
||||
@@ -220,7 +181,6 @@ export const getCreateCompanyWhenAddingNewPersonCodeStepLogicFunctionDefinitions
|
||||
description:
|
||||
'Detects whether an email address belongs to a common personal email provider.',
|
||||
sourceHandlerCode: IS_PERSONAL_EMAIL_LOGIC_FUNCTION_SOURCE,
|
||||
toolInputSchema: IS_PERSONAL_EMAIL_TOOL_INPUT_SCHEMA,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user