diff --git a/components/utopian_labs/actions/get-run-status/get-run-status.mjs b/components/utopian_labs/actions/get-run-status/get-run-status.mjs new file mode 100644 index 0000000000000..8678040dac957 --- /dev/null +++ b/components/utopian_labs/actions/get-run-status/get-run-status.mjs @@ -0,0 +1,22 @@ +import utopianLabs from "../../utopian_labs.app.mjs"; + +export default { + key: "utopian_labs-get-run-status", + name: "Get Run Status", + description: "Retrieve the status of an initiated run. [See the documentation](https://docs.utopianlabs.ai/research#retrieve-research-run-status)", + version: "0.0.1", + type: "action", + props: { + utopianLabs, + runId: { + type: "string", + label: "Run ID", + description: "The ID of the run you want to retrieve the status for", + }, + }, + async run({ $ }) { + const response = await this.utopianLabs.getRunStatus(this.runId); + $.export("$summary", `Successfully retrieved status for run ${this.runId}`); + return response; + }, +}; diff --git a/components/utopian_labs/actions/initiate-classification-run/initiate-classification-run.mjs b/components/utopian_labs/actions/initiate-classification-run/initiate-classification-run.mjs new file mode 100644 index 0000000000000..c828d990c7b07 --- /dev/null +++ b/components/utopian_labs/actions/initiate-classification-run/initiate-classification-run.mjs @@ -0,0 +1,82 @@ +import { + parseArrayAsJSON, + parseObjectEntries, parseStringAsJSON, +} from "../../common/utils.mjs"; +import utopianLabs from "../../utopian_labs.app.mjs"; + +export default { + key: "utopian_labs-initiate-classification-run", + name: "Initiate Classification Run", + description: "Initiate a classification run of the R1-Classification agent. [See the documentation](https://docs.utopianlabs.ai/classification#initiate-a-classification-run)", + version: "0.0.1", + type: "action", + props: { + utopianLabs, + agent: { + propDefinition: [ + utopianLabs, + "agent", + ], + options: [ + { + label: "r1-classification - the default research agent, which has access to a larger set of research sources", + value: "r1-classification", + }, + { + label: "r1-classification-light - the light research agent, more affordable", + value: "r1-classification-light", + }, + ], + }, + lead: { + propDefinition: [ + utopianLabs, + "lead", + ], + description: "The lead to determine the classification for. [See the documentation](https://docs.utopianlabs.ai/types#the-lead-type) for more information. Example: `{ \"company\": { \"website\": \"https://pipedream.com/\" } }`", + }, + options: { + type: "string[]", + label: "Options", + description: "The options to classify the lead into (minimum 2, maximum 10). Each option should be an object such as: `{ \"name\": \"option name\", \"description\": \"option description\" }`", + }, + minResearchSteps: { + propDefinition: [ + utopianLabs, + "minResearchSteps", + ], + }, + maxResearchSteps: { + propDefinition: [ + utopianLabs, + "maxResearchSteps", + ], + }, + context: { + propDefinition: [ + utopianLabs, + "context", + ], + }, + additionalOptions: { + propDefinition: [ + utopianLabs, + "additionalOptions", + ], + description: "Additional parameters to send in the request. [See the documentation](https://docs.utopianlabs.ai/classification#initiate-a-classification-run) for all available parameters. Values will be parsed as JSON where applicable.", + }, + }, + async run({ $ }) { + const response = await this.utopianLabs.initiateRun({ + agent: this.agent, + lead: parseStringAsJSON(this.lead), + options: parseArrayAsJSON(this.options), + min_research_steps: this.minResearchSteps, + max_research_steps: this.maxResearchSteps, + context: this.context, + ...parseObjectEntries(this.additionalOptions), + }); + $.export("$summary", `Successfully initiated run (ID: ${response.id})`); + return response; + }, +}; diff --git a/components/utopian_labs/actions/initiate-copywriting-run/initiate-copywriting-run.mjs b/components/utopian_labs/actions/initiate-copywriting-run/initiate-copywriting-run.mjs new file mode 100644 index 0000000000000..56c1985e7f252 --- /dev/null +++ b/components/utopian_labs/actions/initiate-copywriting-run/initiate-copywriting-run.mjs @@ -0,0 +1,84 @@ +import { LANGUAGE_CODE_OPTIONS } from "../../common/constants.mjs"; +import { + parseObjectEntries, parseStringAsJSON, +} from "../../common/utils.mjs"; +import utopianLabs from "../../utopian_labs.app.mjs"; + +export default { + key: "utopian_labs-initiate-copywriting-run", + name: "Initiate Copywriting Run", + description: "Initiate a copywriting run of the R1-Copywriting agent. [See the documentation](https://docs.utopianlabs.ai/copywriting#initiate-a-copywriting-run)", + version: "0.0.1", + type: "action", + props: { + utopianLabs, + agent: { + propDefinition: [ + utopianLabs, + "agent", + ], + options: [ + { + label: "r1-copywriting - the default research agent, which has access to a larger set of research sources", + value: "r1-copywriting", + }, + { + label: "r1-copywriting-light - the light research agent, more affordable", + value: "r1-copywriting-light", + }, + ], + }, + lead: { + propDefinition: [ + utopianLabs, + "lead", + ], + description: "The lead to write a sales message for. [See the documentation](https://docs.utopianlabs.ai/types#the-lead-type) for more information. Example: `{ \"company\": { \"website\": \"https://pipedream.com/\" } }`", + }, + language: { + type: "string", + label: "Language", + description: "The langauge to write the copy in (defaults to `en-US`)", + optional: true, + options: LANGUAGE_CODE_OPTIONS, + }, + minResearchSteps: { + propDefinition: [ + utopianLabs, + "minResearchSteps", + ], + }, + maxResearchSteps: { + propDefinition: [ + utopianLabs, + "maxResearchSteps", + ], + }, + context: { + propDefinition: [ + utopianLabs, + "context", + ], + }, + additionalOptions: { + propDefinition: [ + utopianLabs, + "additionalOptions", + ], + description: "Additional parameters to send in the request. [See the documentation](https://docs.utopianlabs.ai/copywriting#initiate-a-copywriting-run) for all available parameters. Values will be parsed as JSON where applicable.", + }, + }, + async run({ $ }) { + const response = await this.utopianLabs.initiateRun({ + agent: this.agent, + lead: parseStringAsJSON(this.lead), + language: this.language, + min_research_steps: this.minResearchSteps, + max_research_steps: this.maxResearchSteps, + context: this.context, + ...parseObjectEntries(this.additionalOptions), + }); + $.export("$summary", `Successfully initiated run (ID: ${response.id})`); + return response; + }, +}; diff --git a/components/utopian_labs/actions/initiate-qualification-run/initiate-qualification-run.mjs b/components/utopian_labs/actions/initiate-qualification-run/initiate-qualification-run.mjs new file mode 100644 index 0000000000000..88eef67c6cd33 --- /dev/null +++ b/components/utopian_labs/actions/initiate-qualification-run/initiate-qualification-run.mjs @@ -0,0 +1,75 @@ +import { + parseObjectEntries, parseStringAsJSON, +} from "../../common/utils.mjs"; +import utopianLabs from "../../utopian_labs.app.mjs"; + +export default { + key: "utopian_labs-initiate-qualification-run", + name: "Initiate Qualification Run", + description: "Initiate a qualification run of the R1-Qualification agent. [See the documentation](https://docs.utopianlabs.ai/qualification#initiate-a-qualification-run)", + version: "0.0.1", + type: "action", + props: { + utopianLabs, + agent: { + propDefinition: [ + utopianLabs, + "agent", + ], + options: [ + { + label: "r1-qualification - the default research agent, which has access to a larger set of research sources", + value: "r1-qualification", + }, + { + label: "r1-qualification-light - the light research agent, more affordable", + value: "r1-qualification-light", + }, + ], + }, + lead: { + propDefinition: [ + utopianLabs, + "lead", + ], + description: "The lead to qualify. [See the documentation](https://docs.utopianlabs.ai/types#the-lead-type) for more information. Example: `{ \"company\": { \"website\": \"https://pipedream.com/\" } }`", + }, + minResearchSteps: { + propDefinition: [ + utopianLabs, + "minResearchSteps", + ], + }, + maxResearchSteps: { + propDefinition: [ + utopianLabs, + "maxResearchSteps", + ], + }, + context: { + propDefinition: [ + utopianLabs, + "context", + ], + }, + additionalOptions: { + propDefinition: [ + utopianLabs, + "additionalOptions", + ], + description: "Additional parameters to send in the request. [See the documentation](https://docs.utopianlabs.ai/qualification#initiate-a-qualification-run) for all available parameters. Values will be parsed as JSON where applicable.", + }, + }, + async run({ $ }) { + const response = await this.utopianLabs.initiateRun({ + agent: this.agent, + lead: parseStringAsJSON(this.lead), + min_research_steps: this.minResearchSteps, + max_research_steps: this.maxResearchSteps, + context: this.context, + ...parseObjectEntries(this.additionalOptions), + }); + $.export("$summary", `Successfully initiated run (ID: ${response.id})`); + return response; + }, +}; diff --git a/components/utopian_labs/actions/initiate-research-run/initiate-research-run.mjs b/components/utopian_labs/actions/initiate-research-run/initiate-research-run.mjs new file mode 100644 index 0000000000000..1a64d01460a70 --- /dev/null +++ b/components/utopian_labs/actions/initiate-research-run/initiate-research-run.mjs @@ -0,0 +1,73 @@ +import { + parseObjectEntries, parseStringAsJSON, +} from "../../common/utils.mjs"; +import utopianLabs from "../../utopian_labs.app.mjs"; + +export default { + key: "utopian_labs-initiate-research-run", + name: "Initiate Research Run", + description: "Initiate a research run of the R1 agent. [See the documentation](https://docs.utopianlabs.ai/research#initiate-a-research-run)", + version: "0.0.1", + type: "action", + props: { + utopianLabs, + agent: { + propDefinition: [ + utopianLabs, + "agent", + ], + options: [ + { + label: "r1 - a more powerful agent that has access to a larger set of research sources", + value: "r1", + }, + { + label: "r1-light - a more affordable version of R1", + value: "r1-light", + }, + ], + }, + lead: { + propDefinition: [ + utopianLabs, + "lead", + ], + }, + minResearchSteps: { + propDefinition: [ + utopianLabs, + "minResearchSteps", + ], + }, + maxResearchSteps: { + propDefinition: [ + utopianLabs, + "maxResearchSteps", + ], + }, + context: { + propDefinition: [ + utopianLabs, + "context", + ], + }, + additionalOptions: { + propDefinition: [ + utopianLabs, + "additionalOptions", + ], + }, + }, + async run({ $ }) { + const response = await this.utopianLabs.initiateRun({ + agent: this.agent, + lead: parseStringAsJSON(this.lead), + min_research_steps: this.minResearchSteps, + max_research_steps: this.maxResearchSteps, + context: this.context, + ...parseObjectEntries(this.additionalOptions), + }); + $.export("$summary", `Successfully initiated run (ID: ${response.id})`); + return response; + }, +}; diff --git a/components/utopian_labs/actions/initiate-timing-run/initiate-timing-run.mjs b/components/utopian_labs/actions/initiate-timing-run/initiate-timing-run.mjs new file mode 100644 index 0000000000000..7f762a60a1992 --- /dev/null +++ b/components/utopian_labs/actions/initiate-timing-run/initiate-timing-run.mjs @@ -0,0 +1,75 @@ +import { + parseObjectEntries, parseStringAsJSON, +} from "../../common/utils.mjs"; +import utopianLabs from "../../utopian_labs.app.mjs"; + +export default { + key: "utopian_labs-initiate-timing-run", + name: "Initiate Timing Run", + description: "Initiate a timing run of the R1-Timing agent. [See the documentation](https://docs.utopianlabs.ai/timing#initiate-a-timing-run)", + version: "0.0.1", + type: "action", + props: { + utopianLabs, + agent: { + propDefinition: [ + utopianLabs, + "agent", + ], + options: [ + { + label: "r1-timing - the default research agent, which has access to a larger set of research sources", + value: "r1-timing", + }, + { + label: "r1-timing-light - the light research agent, more affordable", + value: "r1-timing-light", + }, + ], + }, + lead: { + propDefinition: [ + utopianLabs, + "lead", + ], + description: "The lead to determine the timing for. [See the documentation](https://docs.utopianlabs.ai/types#the-lead-type) for more information. Example: `{ \"company\": { \"website\": \"https://pipedream.com/\" } }`", + }, + minResearchSteps: { + propDefinition: [ + utopianLabs, + "minResearchSteps", + ], + }, + maxResearchSteps: { + propDefinition: [ + utopianLabs, + "maxResearchSteps", + ], + }, + context: { + propDefinition: [ + utopianLabs, + "context", + ], + }, + additionalOptions: { + propDefinition: [ + utopianLabs, + "additionalOptions", + ], + description: "Additional parameters to send in the request. [See the documentation](https://docs.utopianlabs.ai/timing#initiate-a-timing-run) for all available parameters. Values will be parsed as JSON where applicable.", + }, + }, + async run({ $ }) { + const response = await this.utopianLabs.initiateRun({ + agent: this.agent, + lead: parseStringAsJSON(this.lead), + min_research_steps: this.minResearchSteps, + max_research_steps: this.maxResearchSteps, + context: this.context, + ...parseObjectEntries(this.additionalOptions), + }); + $.export("$summary", `Successfully initiated run (ID: ${response.id})`); + return response; + }, +}; diff --git a/components/utopian_labs/common/constants.mjs b/components/utopian_labs/common/constants.mjs new file mode 100644 index 0000000000000..870ec1f9c4561 --- /dev/null +++ b/components/utopian_labs/common/constants.mjs @@ -0,0 +1,178 @@ +export const LANGUAGE_CODE_OPTIONS = [ + { + label: "English (United States)", + value: "en-US", + }, + { + label: "English (United Kingdom)", + value: "en-UK", + }, + { + label: "English (Australia)", + value: "en-AU", + }, + { + label: "Dutch (Netherlands)", + value: "nl", + }, + { + label: "German (Germany)", + value: "de", + }, + { + label: "Luxembourgish (Luxembourg)", + value: "lb", + }, + { + label: "French (France)", + value: "fr", + }, + { + label: "Spanish (Spain and Latin America)", + value: "es", + }, + { + label: "Portuguese (Portugal)", + value: "pt", + }, + { + label: "Italian (Italy)", + value: "it", + }, + { + label: "Greek (Greece)", + value: "gr", + }, + { + label: "Russian (Russia)", + value: "ru", + }, + { + label: "Turkish (Turkey)", + value: "tr", + }, + { + label: "Danish (Denmark)", + value: "da", + }, + { + label: "Swedish (Sweden)", + value: "sv", + }, + { + label: "Finnish (Finland)", + value: "fi", + }, + { + label: "Icelandic (Iceland)", + value: "is", + }, + { + label: "Norwegian (Norway)", + value: "no", + }, + { + label: "Chinese (China)", + value: "zh", + }, + { + label: "Japanese (Japan)", + value: "ja", + }, + { + label: "Hindi (India)", + value: "hi", + }, + { + label: "Thai (Thailand)", + value: "th", + }, + { + label: "Vietnamese (Vietnam)", + value: "vi", + }, + { + label: "Burmese (Myanmar)", + value: "my", + }, + { + label: "Korean (Korea)", + value: "ko", + }, + { + label: "Estonian (Estonia)", + value: "et", + }, + { + label: "Lithuanian (Lithuania)", + value: "lt", + }, + { + label: "Latvian (Latvia)", + value: "lv", + }, + { + label: "Macedonian (North Macedonia)", + value: "mk", + }, + { + label: "Indonesian (Indonesia)", + value: "id", + }, + { + label: "Czech (Czech Republic)", + value: "cs", + }, + { + label: "Polish (Poland)", + value: "pl", + }, + { + label: "Slovenian (Slovenia)", + value: "sl", + }, + { + label: "Slovak (Slovakia)", + value: "sk", + }, + { + label: "Bulgarian (Bulgaria)", + value: "bg", + }, + { + label: "Bosnian (Bosnia)", + value: "bs", + }, + { + label: "Hungarian (Hungary)", + value: "hu", + }, + { + label: "Ukrainian (Ukraine)", + value: "uk", + }, + { + label: "Serbian (Serbia)", + value: "sr", + }, + { + label: "Romanian (Romania)", + value: "ro", + }, + { + label: "Albanian (Albania)", + value: "sq", + }, + { + label: "Armenian (Armenia)", + value: "hy", + }, + { + label: "Hebrew (Israel)", + value: "he", + }, + { + label: "Arabic (Various)", + value: "ar", + }, +]; diff --git a/components/utopian_labs/common/utils.mjs b/components/utopian_labs/common/utils.mjs new file mode 100644 index 0000000000000..40131d337bca8 --- /dev/null +++ b/components/utopian_labs/common/utils.mjs @@ -0,0 +1,42 @@ +import { ConfigurationError } from "@pipedream/platform"; + +function optionalParseAsJSON(value) { + try { + return JSON.parse(value); + } catch (e) { + return value; + } +} + +export function parseObjectEntries(value = {}) { + const obj = typeof value === "string" + ? JSON.parse(value) + : value; + return Object.fromEntries( + Object.entries(obj).map(([ + key, + value, + ]) => [ + key, + optionalParseAsJSON(value), + ]), + ); +} + +export function parseStringAsJSON(value) { + try { + return typeof value === "string" + ? JSON.parse(value) + : value; + } catch (err) { + throw new ConfigurationError(`Error parsing JSON string: ${err}`); + } +} + +export function parseArrayAsJSON(value) { + try { + return value.map((item) => JSON.parse(item)); + } catch (err) { + throw new ConfigurationError(`Error parsing JSON string in array: ${err}`); + } +} diff --git a/components/utopian_labs/package.json b/components/utopian_labs/package.json index 7645ebb180ea9..eaa55033b8aec 100644 --- a/components/utopian_labs/package.json +++ b/components/utopian_labs/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/utopian_labs", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Utopian Labs Components", "main": "utopian_labs.app.mjs", "keywords": [ @@ -11,5 +11,9 @@ "author": "Pipedream <support@pipedream.com> (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "utopianlabs": "^0.1.11", + "@pipedream/platform": "^3.0.3" } -} \ No newline at end of file +} diff --git a/components/utopian_labs/utopian_labs.app.mjs b/components/utopian_labs/utopian_labs.app.mjs index 56cad7a7de32f..cac2762b62f7b 100644 --- a/components/utopian_labs/utopian_labs.app.mjs +++ b/components/utopian_labs/utopian_labs.app.mjs @@ -1,11 +1,57 @@ +import { UtopianLabs } from "utopianlabs"; + export default { type: "app", app: "utopian_labs", - propDefinitions: {}, + propDefinitions: { + agent: { + type: "string", + label: "Agent", + description: "The agent to run", + }, + lead: { + type: "object", + label: "Lead", + description: "The lead to research. [See the documentation](https://docs.utopianlabs.ai/types#the-lead-type) for more information. Example: `{ \"company\": { \"website\": \"https://pipedream.com/\" } }`", + }, + minResearchSteps: { + type: "integer", + label: "Minimum Research Steps", + description: "Optionally limit the agent to a minimum amount of research steps (default is 0)", + optional: true, + }, + maxResearchSteps: { + type: "integer", + label: "Maximum Research Steps", + description: "Optionally limit the agent to a maximum amount of research steps (default is 5)", + optional: true, + }, + context: { + type: "string", + label: "Context", + description: "The context for the run. This is a free-form string that will be used to guide the agent's research", + optional: true, + }, + additionalOptions: { + type: "object", + label: "Additional Options", + description: "Additional parameters to send in the request. [See the documentation](https://docs.utopianlabs.ai/research#initiate-a-research-run) for all available parameters. Values will be parsed as JSON where applicable.", + optional: true, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _client() { + return new UtopianLabs({ + apiKey: this.$auth.api_key, + }); + }, + initiateRun(args) { + return this._client().agents.runs.create(args); + }, + getRunStatus(run) { + return this._client().agents.runs.get({ + run, + }); }, }, }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1dfcf62479279..51ecb5423e0ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14033,7 +14033,14 @@ importers: components/usps: {} - components/utopian_labs: {} + components/utopian_labs: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 + utopianlabs: + specifier: ^0.1.11 + version: 0.1.11 components/utradea: {} @@ -15468,14 +15475,6 @@ importers: specifier: ^6.0.0 version: 6.2.0 - modelcontextprotocol/node_modules2/@modelcontextprotocol/sdk/dist/cjs: {} - - modelcontextprotocol/node_modules2/@modelcontextprotocol/sdk/dist/esm: {} - - modelcontextprotocol/node_modules2/zod-to-json-schema/dist/cjs: {} - - modelcontextprotocol/node_modules2/zod-to-json-schema/dist/esm: {} - packages/ai: dependencies: '@pipedream/sdk': @@ -29779,6 +29778,9 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + utopianlabs@0.1.11: + resolution: {integrity: sha512-72vBjQ3/hZHpXYQ6MuOTtcg29xAMSMEL0BFWGN6sgt4bHzPt+p2JwJPEgTTeMs5wP9cpAT1H4Bad4DOqLwRCiw==} + uue@3.1.2: resolution: {integrity: sha512-axKLXVqwtdI/czrjG0X8hyV1KLgeWx8F4KvSbvVCnS+RUvsQMGRjx0kfuZDXXqj0LYvVJmx3B9kWlKtEdRrJLg==} @@ -50107,6 +50109,13 @@ snapshots: utils-merge@1.0.1: {} + utopianlabs@0.1.11: + dependencies: + axios: 1.9.0 + zod: 3.24.4 + transitivePeerDependencies: + - debug + uue@3.1.2: dependencies: escape-string-regexp: 1.0.5