Skip to main content
Glama

mcp-google-sheets

pieces-props.ts16.4 kB
import { Property, InputPropertyMap } from "@activepieces/pieces-framework"; import { httpClient, HttpMethod } from '@activepieces/pieces-common'; import { ImageModel } from 'ai'; import { isNil, SeekPage } from '@activepieces/shared'; import { SUPPORTED_AI_PROVIDERS, SupportedAIProvider } from './supported-ai-providers'; import { AIProviderWithoutSensitiveData } from './types'; export const aiProps = <T extends 'language' | 'image' | 'video'>({ modelType, functionCalling }: AIPropsParams<T>): AIPropsReturn => ({ provider: Property.Dropdown<string, true>({ displayName: 'Provider', required: true, refreshers: [], options: async (_, ctx) => { const { body: { data: supportedProviders } } = await httpClient.sendRequest< SeekPage<AIProviderWithoutSensitiveData> >({ method: HttpMethod.GET, url: `${ctx.server.apiUrl}v1/ai-providers`, headers: { Authorization: `Bearer ${ctx.server.token}`, }, }); if (supportedProviders.length === 0) { return { disabled: true, options: [], placeholder: 'No AI providers configured by the admin.', }; } const providers = supportedProviders.map(supportedProvider => { const provider = SUPPORTED_AI_PROVIDERS.find(p => p.provider === supportedProvider.provider); if (!provider) return null; if (modelType === 'language') { if (provider.languageModels.length === 0) return null; if (functionCalling && !provider.languageModels.some(model => model.functionCalling)) { return null; } } else if (modelType === 'image') { if (provider.imageModels.length === 0) return null; } else if (modelType === 'video') { if (provider.videoModels.length === 0) return null; } return { value: provider.provider, label: provider.displayName }; }); const filteredProviders = providers.filter(p => p !== null); return { placeholder: filteredProviders.length > 0 ? 'Select AI Provider' : `No providers available for ${modelType} models${functionCalling ? ' with function calling' : ''}`, disabled: filteredProviders.length === 0, options: filteredProviders, }; }, }), model: Property.Dropdown({ displayName: 'Model', required: true, defaultValue: 'gpt-4o', refreshers: ['provider'], options: async (propsValue) => { const provider = propsValue['provider'] as string; if (isNil(provider)) { return { disabled: true, options: [], placeholder: 'Select AI Provider', }; } const supportedProvider = SUPPORTED_AI_PROVIDERS.find(p => p.provider === provider); if (isNil(supportedProvider)) { return { disabled: true, options: [], }; } const allModels = modelType === 'language' ? supportedProvider.languageModels : modelType === 'image' ? supportedProvider.imageModels : supportedProvider.videoModels; const models = (modelType === 'language' && functionCalling) ? allModels.filter(model => (model as SupportedAIProvider['languageModels'][number]).functionCalling) : allModels; return { placeholder: 'Select AI Model', disabled: false, options: models.map(model => ({ label: model.displayName, value: model.instance, })), }; }, }), advancedOptions: Property.DynamicProperties({ displayName: 'Advanced Options', required: false, refreshers: ['provider', 'model'], props: async (propsValue): Promise<InputPropertyMap> => { const provider = propsValue['provider'] as unknown as string; const model = propsValue['model'] as unknown as ImageModel; const providerMetadata = SUPPORTED_AI_PROVIDERS.find(p => p.provider === provider); if (isNil(providerMetadata)) { return {}; } let options: InputPropertyMap = {}; if (modelType === 'image') { if (provider === 'openai') { options = { quality: Property.StaticDropdown({ options: { options: model.modelId === 'dall-e-3' ? [ { label: 'Standard', value: 'standard' }, { label: 'HD', value: 'hd' }, ] : model.modelId === 'gpt-image-1' ? [ { label: 'High', value: 'high' }, { label: 'Medium', value: 'medium' }, { label: 'Low', value: 'low' }, ] : [], disabled: model.modelId === 'dall-e-2', }, defaultValue: model.modelId === 'dall-e-3' ? 'standard' : 'high', displayName: 'Image Quality', required: false, }), size: Property.StaticDropdown({ options: { options: model.modelId === 'dall-e-3' ? [ { label: '1024x1024', value: '1024x1024' }, { label: '1792x1024', value: '1792x1024' }, { label: '1024x1792', value: '1024x1792' }, ] : model.modelId === 'gpt-image-1' ? [ { label: '1024x1024', value: '1024x1024' }, { label: '1536x1024', value: '1536x1024' }, { label: '1024x1536', value: '1024x1536' }, ] : [ { label: '256x256', value: '256x256' }, { label: '512x512', value: '512x512' }, { label: '1024x1024', value: '1024x1024' }, ], }, displayName: 'Image Size', required: false, }), } if (model.modelId === 'gpt-image-1') { options = { ...options, background: Property.StaticDropdown({ options: { options: [ { label: 'Auto', value: 'auto' }, { label: 'Transparent', value: 'transparent' }, { label: 'Opaque', value: 'opaque' }, ], }, defaultValue: 'auto', description: 'The background of the image.', displayName: 'Background', required: true, }), } } return options; } if (provider === 'replicate') { options = { negativePrompt: Property.ShortText({ displayName: 'Negative Prompt', required: true, description: 'A prompt to avoid in the generated image.', }), } } if(provider === 'google' && model.modelId === 'gemini-2.5-flash-image-preview') { options = { image: Property.Array({ displayName: 'Images', required:false, properties: { file: Property.File({ displayName: 'Image File', required: true, }), }, description: 'The image(s) you want to edit/merge', }) } } } else if (modelType === 'video') { if (provider === 'google') { if (model.modelId === 'veo-2.0-generate-001') { options = { aspectRatio: Property.StaticDropdown({ displayName: 'Aspect Ratio', required: false, defaultValue: '16:9', options: { options: [ { label: '16:9', value: '16:9' }, { label: '9:16', value: '9:16' }, ], }, }), personGeneration: Property.StaticDropdown({ displayName: 'Person Generation', required: false, options: { options: [ { label: 'Allow Adult', value: 'allow_adult' }, { label: 'Don\'t Allow', value: 'dont_allow' }, { label: 'Allow All', value: 'allow_all' }, ], }, }), } } } } return options; }, }), webSearch: Property.Checkbox({ displayName: 'Web Search', required: false, defaultValue: false, description: 'Whether to use web search to find information for the AI to use in its response.', }), webSearchOptions: Property.DynamicProperties({ displayName: 'Web Search Options', required: false, refreshers: ['webSearch', 'provider', 'model'], props: async (propsValue) => { const webSearchEnabled = propsValue['webSearch'] as unknown as boolean; const provider = propsValue['provider'] as unknown as string; if (!webSearchEnabled) { return {}; } const providerMetadata = SUPPORTED_AI_PROVIDERS.find(p => p.provider === provider); if (isNil(providerMetadata)) { return {}; } let options: InputPropertyMap = { maxUses: Property.Number({ displayName: 'Max Web Search Uses', required: false, defaultValue: 5, description: 'Maximum number of searches to use. Default is 5.', }), includeSources: Property.Checkbox({ displayName: 'Include Sources', description: 'Whether to include the sources in the response. Useful for getting web search details (e.g. search queries, searched URLs, etc).', required: false, defaultValue: false, }), }; const userLocationOptions = { userLocationCity: Property.ShortText({ displayName: 'User Location - City', required: false, description: 'The city name for localizing search results (e.g., San Francisco).', }), userLocationRegion: Property.ShortText({ displayName: 'User Location - Region', required: false, description: 'The region or state for localizing search results (e.g., California).', }), userLocationCountry: Property.ShortText({ displayName: 'User Location - Country', required: false, description: 'The country code for localizing search results (e.g., US).', }), userLocationTimezone: Property.ShortText({ displayName: 'User Location - Timezone', required: false, description: 'The IANA timezone ID for localizing search results (e.g., America/Los_Angeles).', }), }; if (provider === 'anthropic') { options = { ...options, allowedDomains: Property.Array({ displayName: 'Allowed Domains', required: false, description: 'List of domains to search (e.g., example.com, docs.example.com/blog). Domains should not include HTTP/HTTPS scheme. Subdomains are automatically included unless more specific subpaths are provided. Overrides Blocked Domains if both are provided.', properties: { domain: Property.ShortText({ displayName: 'Domain', required: true, }), }, }), blockedDomains: Property.Array({ displayName: 'Blocked Domains', required: false, description: 'List of domains to exclude from search (e.g., example.com, docs.example.com/blog). Domains should not include HTTP/HTTPS scheme. Subdomains are automatically included unless more specific subpaths are provided. Overrided by Allowed Domains if both are provided.', properties: { domain: Property.ShortText({ displayName: 'Domain', required: true, }), }, }), ...userLocationOptions, }; } if (provider === 'openai') { options = { ...options, searchContextSize: Property.StaticDropdown({ displayName: 'Search Context Size', required: false, defaultValue: 'medium', options: { options: [ { label: 'Low', value: 'low' }, { label: 'Medium', value: 'medium' }, { label: 'High', value: 'high' }, ], }, description: 'High level guidance for the amount of context window space to use for the search.', }), ...userLocationOptions, }; } return options; }, }), }) type AIPropsParams<T extends 'language' | 'image' | 'video'> = { modelType: T, functionCalling?: T extends 'language' ? boolean : never } type AIPropsReturn = { provider: ReturnType<typeof Property.Dropdown<string, true>>; model: ReturnType<typeof Property.Dropdown>; advancedOptions: ReturnType<typeof Property.DynamicProperties>; webSearch: ReturnType<typeof Property.Checkbox>; webSearchOptions: ReturnType<typeof Property.DynamicProperties>; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server