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:
martmull
2026-02-16 10:43:29 +01:00
committed by GitHub
parent f694bb99b3
commit da064d5e88
138 changed files with 4839 additions and 367 deletions
@@ -39,6 +39,7 @@ export const SettingsLogicFunctionCodeEditor = ({
if (files.length > 1) {
files.forEach((file) => {
const model = monaco.editor.getModel(monaco.Uri.file(file.path));
if (!isDefined(model)) {
monaco.editor.createModel(
file.content,
@@ -1,10 +1,12 @@
import { type LogicFunctionNewFormValues } from '@/logic-functions/hooks/useLogicFunctionUpdateFormState';
import { type LogicFunctionFormValues } from '@/logic-functions/hooks/useLogicFunctionUpdateFormState';
import { SettingsOptionCardContentCounter } from '@/settings/components/SettingsOptions/SettingsOptionCardContentCounter';
import { SettingsOptionCardContentToggle } from '@/settings/components/SettingsOptions/SettingsOptionCardContentToggle';
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
import { TextArea } from '@/ui/input/components/TextArea';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { H2Title } from 'twenty-ui/display';
import { Section } from 'twenty-ui/layout';
import { H2Title, IconClockHour8, IconTool } from 'twenty-ui/display';
import { Card, Section } from 'twenty-ui/layout';
const StyledInputsContainer = styled.div`
display: flex;
@@ -17,8 +19,10 @@ export const SettingsLogicFunctionNewForm = ({
onChange,
readonly = false,
}: {
formValues: LogicFunctionNewFormValues;
onChange: (key: string) => (value: string) => void;
formValues: LogicFunctionFormValues;
onChange: <TKey extends keyof LogicFunctionFormValues>(
key: TKey,
) => (value: LogicFunctionFormValues[TKey]) => void;
readonly?: boolean;
}) => {
const descriptionTextAreaId = `${formValues.name}-description`;
@@ -48,6 +52,28 @@ export const SettingsLogicFunctionNewForm = ({
onChange={onChange('description')}
readOnly={readonly}
/>
<Card rounded>
<SettingsOptionCardContentToggle
Icon={IconTool}
title={t`Available as tool`}
description={t`When enabled, AI agents and workflow automations can discover and call this function`}
checked={formValues.isTool}
onChange={onChange('isTool')}
disabled={readonly}
/>
</Card>
<Card rounded>
<SettingsOptionCardContentCounter
Icon={IconClockHour8}
title={t`Timeout`}
description={t`Maximum execution time in seconds (1-900)`}
value={formValues.timeoutSeconds}
onChange={onChange('timeoutSeconds')}
minValue={1}
maxValue={900}
disabled={readonly}
/>
</Card>
</StyledInputsContainer>
</Section>
);
@@ -24,7 +24,7 @@ export const SettingsLogicFunctionCodeEditorTab = ({
}: {
files: File[];
handleExecute: () => void;
onChange: (filePath: string, value: string) => void;
onChange: (value: string) => void;
isTesting?: boolean;
}) => {
const activeTabId = useRecoilComponentValue(
@@ -63,9 +63,7 @@ export const SettingsLogicFunctionCodeEditorTab = ({
<SettingsLogicFunctionCodeEditor
files={files}
currentFilePath={activeTabId}
onChange={(newCodeValue: string) =>
onChange(activeTabId, newCodeValue)
}
onChange={(newCodeValue: string) => onChange(newCodeValue)}
/>
)}
</Section>
@@ -7,7 +7,9 @@ export const SettingsLogicFunctionSettingsTab = ({
onChange,
}: {
formValues: LogicFunctionFormValues;
onChange: (key: string) => (value: string) => void;
onChange: <TKey extends keyof LogicFunctionFormValues>(
key: TKey,
) => (value: LogicFunctionFormValues[TKey]) => void;
}) => {
return (
<>