Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { docsbotAuth, docsbotCommon } from '../common';
|
||||
|
||||
export const askQuestion = createAction({
|
||||
auth: docsbotAuth,
|
||||
name: 'askQuestion',
|
||||
displayName: 'Ask Question',
|
||||
description: 'Ask a question to a specific bot in a specific team.',
|
||||
props: docsbotCommon.askQuestionProperties(),
|
||||
async run({ auth: apiKey, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, docsbotCommon.askQuestionSchema);
|
||||
|
||||
const { image_urls, ...restProps } = propsValue;
|
||||
const conversationId = crypto.randomUUID();
|
||||
return await docsbotCommon.askQuestion({
|
||||
apiKey,
|
||||
image_urls: Array.isArray(image_urls)
|
||||
? (image_urls as string[] | undefined)
|
||||
: undefined,
|
||||
conversationId,
|
||||
...(restProps),
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { docsbotAuth, docsbotCommon } from '../common';
|
||||
|
||||
export const createBot = createAction({
|
||||
auth: docsbotAuth,
|
||||
name: 'createBot',
|
||||
displayName: 'Create Bot',
|
||||
description: 'Creates a new bot.',
|
||||
props: docsbotCommon.createBotProperties(),
|
||||
async run({ auth: apiKey, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, docsbotCommon.createBotSchema);
|
||||
|
||||
return await docsbotCommon.createBot({
|
||||
apiKey,
|
||||
...propsValue,
|
||||
language: propsValue.language as 'en' | 'jp',
|
||||
privacy: propsValue.privacy as 'public' | 'private',
|
||||
model: propsValue.model as "string" | undefined,
|
||||
embeddingModel: propsValue.embeddingModel as
|
||||
| "text-embedding-ada-002"
|
||||
| "text-embedding-3-large"
|
||||
| "text-embedding-3-small"
|
||||
| "embed-multilingual-v3.0"
|
||||
| "embed-v4.0"
|
||||
| undefined,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import z from 'zod';
|
||||
import { docsbotAuth, docsbotCommon } from '../common';
|
||||
import { createSourceParams } from '../common/types';
|
||||
|
||||
export const createSource = createAction({
|
||||
auth: docsbotAuth,
|
||||
name: 'createSource',
|
||||
displayName: 'Create Source',
|
||||
description: 'Create a new source for a bot.',
|
||||
props: docsbotCommon.createSourceProperties(),
|
||||
async run({ auth: apiKey, propsValue }) {
|
||||
// Some fields are conditionally required, so we need to use Zod validation manually here
|
||||
const { sourceProperties, ...props } = propsValue;
|
||||
const parsedProps: createSourceParams = {
|
||||
...props,
|
||||
...sourceProperties,
|
||||
};
|
||||
try {
|
||||
await docsbotCommon.createSourceSchema.parseAsync(parsedProps);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
const errors = error.issues.reduce((acc: Record<string, string>, err: z.ZodIssue) => {
|
||||
const path = err.path.join('.');
|
||||
return {
|
||||
...acc,
|
||||
[path]: err.message,
|
||||
};
|
||||
}, {});
|
||||
throw new Error(JSON.stringify({ errors }, null, 2));
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
const { faqs, ...restProps } = parsedProps;
|
||||
|
||||
return await docsbotCommon.createSource({
|
||||
apiKey,
|
||||
...restProps,
|
||||
faqs: faqs as { question: string; answer: string }[] | undefined,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { docsbotAuth, docsbotCommon } from '../common';
|
||||
|
||||
export const findBot = createAction({
|
||||
auth: docsbotAuth,
|
||||
name: 'findBot',
|
||||
displayName: 'Find Bot',
|
||||
description: 'Finds bot by name.',
|
||||
props: docsbotCommon.findBotProperties(),
|
||||
async run({ auth: apiKey, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, docsbotCommon.findBotSchema);
|
||||
|
||||
const { teamId, name } = propsValue;
|
||||
const teamBots = await docsbotCommon.listBots({
|
||||
apiKey,
|
||||
teamId,
|
||||
});
|
||||
const needle = (name ?? '').trim().toLowerCase();
|
||||
// Try to find case-insensitive and partial match
|
||||
const bot = teamBots.filter((bot) =>
|
||||
(bot.name ?? '').toLowerCase().includes(needle)
|
||||
);
|
||||
|
||||
if (bot.length === 0) {
|
||||
throw new Error(
|
||||
`No bot found with a name containing "${name}" in the selected team.`
|
||||
);
|
||||
}
|
||||
|
||||
return bot;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { docsbotAuth, docsbotCommon } from '../common';
|
||||
|
||||
export const uploadSourceFile = createAction({
|
||||
auth: docsbotAuth,
|
||||
name: 'uploadSourceFile',
|
||||
displayName: 'Upload Source File',
|
||||
description: 'Upload a file to be used as a source.',
|
||||
props: docsbotCommon.uploadSourceFileProperties(),
|
||||
async run({ auth: apiKey, propsValue }) {
|
||||
console.log("file:", propsValue.file, typeof propsValue.file);
|
||||
await propsValidation.validateZod(
|
||||
propsValue,
|
||||
docsbotCommon.uploadSourceFileSchema
|
||||
);
|
||||
|
||||
const { botId, file, teamId } = propsValue;
|
||||
const presignedUrl = await docsbotCommon.createPresignedFileUploadURL({
|
||||
apiKey,
|
||||
teamId,
|
||||
botId,
|
||||
fileName: file.filename,
|
||||
});
|
||||
await docsbotCommon.uploadFileToCloudStorage({
|
||||
uploadUrl: presignedUrl.url,
|
||||
file: file.data,
|
||||
});
|
||||
return presignedUrl;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,158 @@
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { PieceAuth } from '@activepieces/pieces-framework';
|
||||
import * as properties from './properties';
|
||||
import * as schemas from './schemas';
|
||||
import {
|
||||
askQuestionRequestParams,
|
||||
Bot,
|
||||
createBotRequestParams,
|
||||
createSourceRequestParams,
|
||||
listBotsParams,
|
||||
PresignedUpdateUrlResponse,
|
||||
Team,
|
||||
createSourceUrlParams as teamAndBotUrlParams,
|
||||
uploadSourceFileRequestParams,
|
||||
uploadToCloudStorageParams,
|
||||
} from './types';
|
||||
|
||||
export const docsbotAuth = PieceAuth.SecretText({
|
||||
displayName: 'API Key',
|
||||
required: true,
|
||||
description: 'The API key for authenticating with DocsBot.',
|
||||
});
|
||||
|
||||
export const docsbotCommon = {
|
||||
// API Info
|
||||
baseUrl: 'https://docsbot.ai/api',
|
||||
endpoints: {
|
||||
askQuestion: ({ teamId, botId }: teamAndBotUrlParams) =>
|
||||
`https://api.docsbot.ai/teams/${teamId}/bots/${botId}/chat-agent`,
|
||||
createSource: ({ teamId, botId }: teamAndBotUrlParams) =>
|
||||
`${docsbotCommon.baseUrl}/teams/${teamId}/bots/${botId}/sources`,
|
||||
createBot: (teamId: string) =>
|
||||
`${docsbotCommon.baseUrl}/teams/${teamId}/bots`,
|
||||
createPresignedFileUploadURL: ({ teamId, botId }: teamAndBotUrlParams) =>
|
||||
`${docsbotCommon.baseUrl}/teams/${teamId}/bots/${botId}/upload-url`,
|
||||
listTeams: () => `${docsbotCommon.baseUrl}/teams`,
|
||||
listBots: (teamId: string) =>
|
||||
`${docsbotCommon.baseUrl}/teams/${teamId}/bots`,
|
||||
},
|
||||
|
||||
// Properties
|
||||
askQuestionProperties: properties.askQuestion,
|
||||
createSourceProperties: properties.createSource,
|
||||
uploadSourceFileProperties: properties.uploadSourceFile,
|
||||
createBotProperties: properties.createBot,
|
||||
findBotProperties: properties.findBot,
|
||||
|
||||
// Schemas
|
||||
askQuestionSchema: schemas.askQuestion,
|
||||
createSourceSchema: schemas.createSource,
|
||||
uploadSourceFileSchema: schemas.uploadSourceFile,
|
||||
createBotSchema: schemas.createBot,
|
||||
findBotSchema: schemas.findBot,
|
||||
|
||||
// Methods
|
||||
askQuestion: async ({
|
||||
apiKey,
|
||||
teamId,
|
||||
botId,
|
||||
...chatParams
|
||||
}: askQuestionRequestParams) => {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: docsbotCommon.endpoints.askQuestion({ teamId, botId }),
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey.secret_text}`,
|
||||
},
|
||||
body: { ...chatParams },
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
createSource: async ({
|
||||
apiKey,
|
||||
teamId,
|
||||
botId,
|
||||
...sourceParams
|
||||
}: createSourceRequestParams) => {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: docsbotCommon.endpoints.createSource({
|
||||
teamId: teamId,
|
||||
botId: botId,
|
||||
}),
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey.secret_text}`,
|
||||
},
|
||||
body: { ...sourceParams },
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
createBot: async ({
|
||||
apiKey,
|
||||
teamId,
|
||||
...botParams
|
||||
}: createBotRequestParams) => {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: docsbotCommon.endpoints.createBot(teamId),
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey.secret_text}`,
|
||||
},
|
||||
body: { ...botParams },
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
createPresignedFileUploadURL: async ({
|
||||
apiKey,
|
||||
teamId,
|
||||
botId,
|
||||
fileName,
|
||||
}: uploadSourceFileRequestParams) => {
|
||||
const response = await httpClient.sendRequest<PresignedUpdateUrlResponse>({
|
||||
method: HttpMethod.GET,
|
||||
url: docsbotCommon.endpoints.createPresignedFileUploadURL({
|
||||
teamId,
|
||||
botId,
|
||||
}) + `?fileName=${encodeURIComponent(fileName)}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey.secret_text}`,
|
||||
},
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
uploadFileToCloudStorage: async ({
|
||||
uploadUrl,
|
||||
file,
|
||||
}: uploadToCloudStorageParams) => {
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.PUT,
|
||||
url: uploadUrl,
|
||||
headers: {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
},
|
||||
body: file,
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
listBots: async ({ apiKey, teamId }: listBotsParams) => {
|
||||
const resonse = await httpClient.sendRequest<Bot[]>({
|
||||
method: HttpMethod.GET,
|
||||
url: docsbotCommon.endpoints.listBots(teamId),
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey.secret_text}`,
|
||||
},
|
||||
});
|
||||
return resonse.body;
|
||||
},
|
||||
listTeams: async (apiKey: string) => {
|
||||
const response = await httpClient.sendRequest<Team[]>({
|
||||
method: HttpMethod.GET,
|
||||
url: docsbotCommon.endpoints.listTeams(),
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
},
|
||||
});
|
||||
return response.body;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,324 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { docsbotAuth, docsbotCommon } from '.';
|
||||
|
||||
// Base reusable properties
|
||||
const teamProperty = ({
|
||||
displayName,
|
||||
description,
|
||||
}: {
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
}) =>
|
||||
Property.Dropdown({
|
||||
auth: docsbotAuth,
|
||||
displayName: displayName || 'Team',
|
||||
description: description || 'The team to use.',
|
||||
required: true,
|
||||
refreshers: ['auth'],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const teams = await docsbotCommon.listTeams(auth.secret_text);
|
||||
return {
|
||||
options: teams.map((team) => ({
|
||||
label: team.name,
|
||||
value: team.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const botProperty = ({
|
||||
displayName,
|
||||
description,
|
||||
}: {
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
}) =>
|
||||
Property.ShortText({
|
||||
displayName: displayName || 'Bot',
|
||||
description: description || 'The bot to use.',
|
||||
required: true,
|
||||
});
|
||||
|
||||
// Action properties
|
||||
|
||||
export const askQuestion = () => ({
|
||||
teamId: teamProperty({}),
|
||||
botId: botProperty({}),
|
||||
question: Property.LongText({
|
||||
displayName: 'Question',
|
||||
required: true,
|
||||
description:
|
||||
'The question to ask the bot. 2 to 500 characters. Max increased to 8K tokens (roughtly 32k chars) when authenticated.',
|
||||
}),
|
||||
metadata: Property.Object({
|
||||
displayName: 'Metadata',
|
||||
description:
|
||||
'A user identification object with arbitrary metadata about the user. Will be saved to the question and conversation. Keys referrer, email, and name are shown in question history logs. Optional, defaults to null.',
|
||||
required: false,
|
||||
}),
|
||||
context_items: Property.Number({
|
||||
displayName: 'Context Items',
|
||||
description:
|
||||
'Number of sources to lookup for the bot to answer from. Optional, default is 5. Research mode uses 16 (more expensive token usage).',
|
||||
required: false,
|
||||
}),
|
||||
human_escalation: Property.Checkbox({
|
||||
displayName: 'Human Escalation',
|
||||
description:
|
||||
'Whether to enable human escalation for this question. Optional, default is false.',
|
||||
required: false,
|
||||
}),
|
||||
followup_rating: Property.Checkbox({
|
||||
displayName: 'Follow-up Rating',
|
||||
description:
|
||||
'Whether to ask the user for a follow-up rating after the question is answered. Optional, default is false.',
|
||||
required: false,
|
||||
}),
|
||||
document_retriever: Property.Checkbox({
|
||||
displayName: 'Document Retriever',
|
||||
description:
|
||||
'Whether to use the document retriever for this question. Optional, default is false.',
|
||||
required: false,
|
||||
}),
|
||||
full_source: Property.Checkbox({
|
||||
displayName: 'Full Source',
|
||||
description:
|
||||
'Whether to return the full source content in the response. Optional, default is false.',
|
||||
required: false,
|
||||
}),
|
||||
autocut: Property.Number({
|
||||
displayName: 'Autocut',
|
||||
description: 'Autocut results to num groups. Optional, defaults to false.',
|
||||
required: false,
|
||||
}),
|
||||
testing: Property.Checkbox({
|
||||
displayName: 'Testing',
|
||||
description:
|
||||
'Whether the request is for testing purposes. Optional, defaults to false.',
|
||||
required: false,
|
||||
}),
|
||||
image_urls: Property.Array({
|
||||
displayName: 'Image URLs',
|
||||
description:
|
||||
'List of image URLs to include with the question as context. Optional, defaults to null.',
|
||||
required: false,
|
||||
}),
|
||||
model: Property.ShortText({
|
||||
displayName: 'Model',
|
||||
description:
|
||||
'Override the model used for this request. Requires an OpenAI API key to be set on your team. Optional, defaults to the model configured for the bot.',
|
||||
required: false,
|
||||
}),
|
||||
default_language: Property.ShortText({
|
||||
displayName: 'Default Language',
|
||||
description:
|
||||
"The default language to use if the language of the conversation is unclear. Use locale codes like 'en' or 'en-US'. Optional, defaults to the bot's configured language.",
|
||||
required: false,
|
||||
}),
|
||||
reasoning_effort: Property.StaticDropdown({
|
||||
displayName: 'Reasoning Effort',
|
||||
description:
|
||||
'Reasoning depth for the response. Requires authentication to override default.',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Minimal', value: 'minimal' },
|
||||
{ label: 'Low', value: 'low' },
|
||||
{ label: 'Medium', value: 'medium' },
|
||||
{ label: 'High', value: 'high' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
export const createSource = () => ({
|
||||
teamId: teamProperty({}),
|
||||
botId: botProperty({}),
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
description:
|
||||
'Can be url, document, sitemap, wp, urls, csv, rss, qa, youtube. All but url, sitemap, and youtube require uploading a formatted file.',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'URL', value: 'url' },
|
||||
{ label: 'Document', value: 'document' },
|
||||
{ label: 'Sitemap', value: 'sitemap' },
|
||||
{ label: 'WP', value: 'wp' },
|
||||
{ label: 'Multiple URLs', value: 'urls' },
|
||||
{ label: 'CSV', value: 'csv' },
|
||||
{ label: 'RSS', value: 'rss' },
|
||||
{ label: 'Q&A', value: 'qa' },
|
||||
{ label: 'YouTube', value: 'youtube' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
sourceProperties: Property.DynamicProperties({
|
||||
auth: docsbotAuth,
|
||||
displayName: 'Source Properties',
|
||||
description: 'Create Source Properties',
|
||||
required: true,
|
||||
refreshers: ['auth', 'type'],
|
||||
props: async ({ type }) => {
|
||||
return {
|
||||
title: Property.ShortText({
|
||||
displayName: 'Title',
|
||||
description: 'The source title. Required only for document type.',
|
||||
required:
|
||||
typeof type === 'string' && type === 'document' ? true : false,
|
||||
}),
|
||||
url: Property.ShortText({
|
||||
displayName: 'URL',
|
||||
description:
|
||||
'The source url. Optional except for url, sitemap, youtube, and rss types.',
|
||||
required:
|
||||
typeof type === 'string' &&
|
||||
['url', 'sitemap', 'youtube', 'rss'].includes(type)
|
||||
? true
|
||||
: false,
|
||||
}),
|
||||
file: Property.ShortText({
|
||||
displayName: 'File URL',
|
||||
description:
|
||||
'The source file path. Required if type is urls, csv, document, or wp. The is usually the cloud storage path from the Upload Source File action.',
|
||||
required:
|
||||
typeof type === 'string' &&
|
||||
['urls', 'csv', 'document', 'wp'].includes(type)
|
||||
? true
|
||||
: false,
|
||||
}),
|
||||
faqs: Property.Array({
|
||||
displayName: 'FAQs',
|
||||
description:
|
||||
'An array of question and answer objects. Required if type is qa.',
|
||||
required: typeof type === 'string' && type === 'qa' ? true : false,
|
||||
|
||||
properties: {
|
||||
question: Property.LongText({
|
||||
displayName: 'Question',
|
||||
required: true,
|
||||
description: 'The question.',
|
||||
}),
|
||||
answer: Property.LongText({
|
||||
displayName: 'Answer',
|
||||
required: true,
|
||||
description: 'The answer.',
|
||||
}),
|
||||
},
|
||||
}),
|
||||
scheduleInterval: Property.StaticDropdown({
|
||||
displayName: 'Schedule Interval',
|
||||
description:
|
||||
'The source refresh scheduled interval. Can be daily, weekly, monthly, or none depending on your plan. Optional, defaults to none.',
|
||||
required: false,
|
||||
defaultValue: 'none',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Daily', value: 'daily' },
|
||||
{ label: 'Weekly', value: 'weekly' },
|
||||
{ label: 'Monthly', value: 'monthly' },
|
||||
{ label: 'None', value: 'none' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
export const uploadSourceFile = () => ({
|
||||
teamId: teamProperty({}),
|
||||
botId: botProperty({}),
|
||||
file: Property.File({
|
||||
displayName: 'File',
|
||||
description: 'The file to upload.',
|
||||
required: true,
|
||||
}),
|
||||
});
|
||||
|
||||
export const createBot = () => ({
|
||||
teamId: teamProperty({}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'Name',
|
||||
description: 'The bot name. Used publically.',
|
||||
required: true,
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Description',
|
||||
description:
|
||||
'The bot description. Shown by default in embeds and share links.',
|
||||
required: true,
|
||||
}),
|
||||
privacy: Property.StaticDropdown({
|
||||
displayName: 'Privacy',
|
||||
description: 'The bot privacy. Can be public or private.',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Public', value: 'public' },
|
||||
{ label: 'Private', value: 'private' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
language: Property.StaticDropdown({
|
||||
displayName: 'Language',
|
||||
description: 'The bot language.',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'English', value: 'en' },
|
||||
{ label: 'Japanese', value: 'jp' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
model: Property.StaticDropdown({
|
||||
displayName: 'Model',
|
||||
description: 'The OpenAI model.',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'GPT-4.1', value: 'gpt-4.1' },
|
||||
{ label: 'GPT-4.1 Mini', value: 'gpt-4.1-mini' },
|
||||
{ label: 'GPT-4o', value: 'gpt-4o' },
|
||||
{ label: 'GPT-4o Mini', value: 'gpt-4o-mini' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
embeddingModel: Property.StaticDropdown({
|
||||
displayName: 'Embedding Model',
|
||||
description:
|
||||
'The embedding model. Currently supports text-embedding-ada-002, text-embedding-3-large, text-embedding-3-small, embed-multilingual-v3.0, and embed-v4.0 (Cohere) depending on your plan.',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Text Embedding ADA 002', value: 'text-embedding-ada-002' },
|
||||
{ label: 'Text Embedding 3 Large', value: 'text-embedding-3-large' },
|
||||
{ label: 'Text Embedding 3 Small', value: 'text-embedding-3-small' },
|
||||
{ label: 'Embed Multilingual V3.0', value: 'embed-multilingual-v3.0' },
|
||||
{ label: 'Embed V4.0', value: 'embed-v4.0' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
copyFrom: Property.ShortText({
|
||||
displayName: 'Copy From',
|
||||
description:
|
||||
'The ID of an existing bot in your team to copy from. If provided, the new bot will be created as a copy of the specified bot, with all sources copied over after creation.',
|
||||
required: false,
|
||||
}),
|
||||
});
|
||||
|
||||
export const findBot = () => ({
|
||||
teamId: teamProperty({}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'Name',
|
||||
description: 'The bot name.',
|
||||
required: true,
|
||||
}),
|
||||
});
|
||||
@@ -0,0 +1,118 @@
|
||||
import z from 'zod';
|
||||
|
||||
export const askQuestion = {
|
||||
teamId: z.string(),
|
||||
botId: z.string(),
|
||||
question: z.string(),
|
||||
metadata: z.object({}).optional(),
|
||||
context_items: z.number().min(1).optional(),
|
||||
human_escalation: z.boolean().optional(),
|
||||
followup_rating: z.boolean().optional(),
|
||||
document_retriever: z.boolean().optional(),
|
||||
full_source: z.boolean().optional(),
|
||||
autocut: z.number().optional(),
|
||||
testing: z.boolean().optional(),
|
||||
image_urls: z.array(z.string().url()).optional(),
|
||||
model: z.string().optional(),
|
||||
default_language: z.string().optional(),
|
||||
reasoning_effort: z.enum(['minimal', 'low', 'medium', 'high']).optional(),
|
||||
};
|
||||
|
||||
export const createSource = z
|
||||
.object({
|
||||
type: z.enum([
|
||||
'url',
|
||||
'document',
|
||||
'sitemap',
|
||||
'wp',
|
||||
'urls',
|
||||
'csv',
|
||||
'rss',
|
||||
'qa',
|
||||
'youtube',
|
||||
]),
|
||||
title: z.string().optional(),
|
||||
url: z.string().url().optional(),
|
||||
file: z.string().optional(),
|
||||
faqs: z
|
||||
.array(
|
||||
z.object({
|
||||
question: z.string(),
|
||||
answer: z.string(),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
scheduleInterval: z.enum(['daily', 'weekly', 'monthly', 'none']).optional(),
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
if (data.type === 'document' && (!data.title || data.title.trim() === '')) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ['title'],
|
||||
message: '"title" is required when type is "document".',
|
||||
});
|
||||
}
|
||||
if (
|
||||
['url', 'sitemap', 'youtube', 'rss'].includes(data.type) &&
|
||||
(!data.url || data.url.trim() === '')
|
||||
) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ['url'],
|
||||
message:
|
||||
'"url" is required when type is "url", "sitemap", "youtube", or "rss".',
|
||||
});
|
||||
}
|
||||
if (
|
||||
['urls', 'csv', 'document', 'wp'].includes(data.type) &&
|
||||
(!data.file || data.file.trim() === '')
|
||||
) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ['file'],
|
||||
message:
|
||||
'"file" is required when type is "urls", "csv", "document", or "wp".',
|
||||
});
|
||||
}
|
||||
if (data.type === 'qa' && (!data.faqs || data.faqs.length === 0)) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ['faqs'],
|
||||
message: '"faqs" is required when type is "qa".',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export const uploadSourceFile = {
|
||||
teamId: z.string(),
|
||||
botId: z.string(),
|
||||
file: z.object({
|
||||
filename: z.string(),
|
||||
data: z.instanceof(Buffer),
|
||||
extension: z.string().optional(),
|
||||
}),
|
||||
};
|
||||
|
||||
export const createBot = {
|
||||
teamId: z.string(),
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
privacy: z.enum(['public', 'private']),
|
||||
language: z.enum(['en', 'jp']),
|
||||
model: z.string().optional(),
|
||||
embeddingModel: z
|
||||
.enum([
|
||||
'text-embedding-ada-002',
|
||||
'text-embedding-3-large',
|
||||
'text-embedding-3-small',
|
||||
'embed-multilingual-v3.0',
|
||||
'embed-v4.0',
|
||||
])
|
||||
.optional(),
|
||||
copyFrom: z.string().optional(),
|
||||
};
|
||||
|
||||
export const findBot = {
|
||||
teamId: z.string(),
|
||||
name: z.string(),
|
||||
};
|
||||
@@ -0,0 +1,125 @@
|
||||
import { AppConnectionValueForAuthProperty } from "@activepieces/pieces-framework";
|
||||
import { docsbotAuth } from ".";
|
||||
|
||||
export type createSourceUrlParams = {
|
||||
teamId: string;
|
||||
botId: string;
|
||||
};
|
||||
|
||||
export interface AuthenticationParams {
|
||||
apiKey: AppConnectionValueForAuthProperty<typeof docsbotAuth>;
|
||||
}
|
||||
|
||||
export interface askQuestionRequestParams extends AuthenticationParams {
|
||||
teamId: string;
|
||||
botId: string;
|
||||
stream?: boolean;
|
||||
conversationId: string;
|
||||
question: string;
|
||||
metadata?: object;
|
||||
context_items?: number;
|
||||
human_escalation?: boolean;
|
||||
followup_rating?: boolean;
|
||||
document_retriever?: boolean;
|
||||
full_source?: boolean;
|
||||
autocut?: number | boolean;
|
||||
testing?: boolean;
|
||||
image_urls?: string[];
|
||||
model?: string;
|
||||
default_language?: string;
|
||||
reasoning_effort?: string;
|
||||
}
|
||||
|
||||
export interface createSourceParams {
|
||||
teamId: string;
|
||||
botId: string;
|
||||
type: string;
|
||||
title?: string;
|
||||
url?: string;
|
||||
file?: string;
|
||||
faqs?: { question: string; answer: string }[];
|
||||
scheduleInterval?: string;
|
||||
}
|
||||
export interface createSourceRequestParams
|
||||
extends AuthenticationParams,
|
||||
createSourceParams {}
|
||||
|
||||
export interface createBotRequestParams extends AuthenticationParams {
|
||||
teamId: string;
|
||||
name: string;
|
||||
description: string;
|
||||
privacy: 'public' | 'private';
|
||||
language: 'en' | 'jp';
|
||||
model?: 'string';
|
||||
embeddingModel?:
|
||||
| 'text-embedding-ada-002'
|
||||
| 'text-embedding-3-large'
|
||||
| 'text-embedding-3-small'
|
||||
| 'embed-multilingual-v3.0'
|
||||
| 'embed-v4.0';
|
||||
copyFrom?: string;
|
||||
}
|
||||
|
||||
export interface findBotParams extends AuthenticationParams {
|
||||
teamId: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface uploadSourceFileRequestParams extends AuthenticationParams {
|
||||
teamId: string;
|
||||
botId: string;
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
export interface uploadToCloudStorageParams {
|
||||
uploadUrl: string;
|
||||
file: Buffer;
|
||||
}
|
||||
|
||||
export interface listBotsParams extends AuthenticationParams {
|
||||
teamId: string;
|
||||
}
|
||||
|
||||
// API Response Objects
|
||||
export interface Team {
|
||||
id: string;
|
||||
roles: Record<string, string>[];
|
||||
name: string;
|
||||
createdAt: string;
|
||||
status: string;
|
||||
questionCount: number;
|
||||
pageCount: number;
|
||||
sourceCount: number;
|
||||
chunkCount: number;
|
||||
openAIKey: string;
|
||||
botCount: number;
|
||||
plan: {
|
||||
name: string;
|
||||
bots: number;
|
||||
sources: number;
|
||||
pages: number;
|
||||
questions: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Bot {
|
||||
id: string;
|
||||
questionCount: number;
|
||||
name: string;
|
||||
description: string;
|
||||
privacy: 'public' | 'private';
|
||||
indexId: string;
|
||||
customPrompt: null;
|
||||
language: string;
|
||||
model: string;
|
||||
createdAt: string;
|
||||
sourceCount: number;
|
||||
pageCount: number;
|
||||
chunkCount: number;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface PresignedUpdateUrlResponse {
|
||||
url: string;
|
||||
file: string;
|
||||
}
|
||||
Reference in New Issue
Block a user