├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── feature_request.yml │ └── integration_request.yml ├── PULL_REQUEST_TEMPLATE.md ├── scripts │ ├── integration_detect_changed_files.sh │ ├── integration_generate_pr_content.sh │ └── integration_pr_review.py └── workflows │ ├── backend.yml │ ├── devportal.yml │ └── integration_code_review.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CLA.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── backend ├── .dockerignore ├── .env.example ├── .gitignore ├── .prettierrc.json ├── .python-version ├── Dockerfile.runner ├── Dockerfile.server ├── README.md ├── aci │ ├── __init__.py │ ├── alembic │ │ ├── README │ │ ├── env.py │ │ ├── script.py.mako │ │ └── versions │ │ │ ├── 2025_01_10_1906-c6f47d7d2fa1_first_migration.py │ │ │ ├── 2025_01_27_1657-adcfaa729f61_added_custom_instructions_to_agent_table.py │ │ │ ├── 2025_02_10_2318-6482e8fa201e_store_app_name_function_name_for_non_.py │ │ │ ├── 2025_03_08_1922-70dd635d80d4_add_new_protocol_enum_value.py │ │ │ ├── 2025_03_10_2339-28702a5576f5_change_agent_level_app_function_acl.py │ │ │ ├── 2025_03_11_2315-949afaf258c3_json_to_jsonb.py │ │ │ ├── 2025_03_14_2000-1b82aeb7431f_create_secret_table.py │ │ │ ├── 2025_04_11_1232-7a159de1064c_add_nullable_org_id_column.py │ │ │ ├── 2025_04_11_1236-a79cdd14460e_make_org_id_of_project_table_not_.py │ │ │ ├── 2025_04_11_1237-af2ecf7ca19a_drop_owner_id_column_of_project_table.py │ │ │ ├── 2025_04_11_1238-bce2fbe6273b_drop_user_entity_organization_etc_tables.py │ │ │ ├── 2025_04_15_0929-c5978747c602_add_encrypted_key_and_key_hmac_columns_.py │ │ │ ├── 2025_04_15_0930-0846452f51ac_drop_the_key_column_of_the_api_keys_.py │ │ │ ├── 2025_04_15_0932-7ecafab6f8f9_rename_encrypted_key_column_to_key_and_.py │ │ │ ├── 2025_04_29_1220-ce439f017e25_add_last_used_at_to_linked_accounts.py │ │ │ └── 2025_05_03_1026-068b47f44d83_add_billing_related_tables.py │ ├── cli │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── aci.py │ │ ├── commands │ │ │ ├── __init__.py │ │ │ ├── billing.py │ │ │ ├── create_agent.py │ │ │ ├── create_project.py │ │ │ ├── create_random_api_key.py │ │ │ ├── delete_app.py │ │ │ ├── fuzzy_test_function_execution.py │ │ │ ├── get_app.py │ │ │ ├── rename_app.py │ │ │ ├── update_agent.py │ │ │ ├── upsert_app.py │ │ │ └── upsert_functions.py │ │ ├── config.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── test_upsert_app.py │ │ │ └── test_upsert_functions.py │ ├── common │ │ ├── __init__.py │ │ ├── config.py │ │ ├── db │ │ │ ├── crud │ │ │ │ ├── __init__.py │ │ │ │ ├── app_configurations.py │ │ │ │ ├── apps.py │ │ │ │ ├── functions.py │ │ │ │ ├── linked_accounts.py │ │ │ │ ├── plans.py │ │ │ │ ├── processed_stripe_event.py │ │ │ │ ├── projects.py │ │ │ │ ├── secret.py │ │ │ │ └── subscriptions.py │ │ │ ├── custom_sql_types.py │ │ │ └── sql_models.py │ │ ├── embeddings.py │ │ ├── encryption.py │ │ ├── enums.py │ │ ├── exceptions.py │ │ ├── logging_setup.py │ │ ├── processor.py │ │ ├── schemas │ │ │ ├── __init__.py │ │ │ ├── agent.py │ │ │ ├── analytics.py │ │ │ ├── apikey.py │ │ │ ├── app.py │ │ │ ├── app_configurations.py │ │ │ ├── app_connectors │ │ │ │ └── agent_secrets_manager.py │ │ │ ├── function.py │ │ │ ├── linked_accounts.py │ │ │ ├── plans.py │ │ │ ├── project.py │ │ │ ├── secret.py │ │ │ ├── security_scheme.py │ │ │ └── subscription.py │ │ ├── test_utils.py │ │ ├── tests │ │ │ ├── __init__.py │ │ │ ├── crud │ │ │ │ ├── __init__.py │ │ │ │ └── test_linked_accounts.py │ │ │ └── test_processor_filter_visible_properties.py │ │ ├── utils.py │ │ ├── validator.py │ │ └── validators │ │ │ ├── __init__.py │ │ │ └── security_scheme.py │ └── server │ │ ├── __init__.py │ │ ├── acl.py │ │ ├── agent │ │ ├── __init__.py │ │ ├── meta_functions.py │ │ ├── prompt.py │ │ └── types.py │ │ ├── app_connectors │ │ ├── __init__.py │ │ ├── agent_secrets_manager.py │ │ ├── base.py │ │ ├── e2b.py │ │ ├── gmail.py │ │ ├── mock_app_connector.py │ │ └── vercel.py │ │ ├── config.py │ │ ├── context.py │ │ ├── custom_instructions.py │ │ ├── dependencies.py │ │ ├── dependency_check.py │ │ ├── function_executors │ │ ├── __init__.py │ │ ├── base_executor.py │ │ ├── connector_function_executor.py │ │ ├── rest_api_key_function_executor.py │ │ ├── rest_function_executor.py │ │ ├── rest_no_auth_function_executor.py │ │ └── rest_oauth2_function_executor.py │ │ ├── main.py │ │ ├── middleware │ │ ├── __init__.py │ │ ├── interceptor.py │ │ └── ratelimit.py │ │ ├── oauth2_manager.py │ │ ├── quota_manager.py │ │ ├── routes │ │ ├── __init__.py │ │ ├── agent.py │ │ ├── analytics.py │ │ ├── app_configurations.py │ │ ├── apps.py │ │ ├── billing.py │ │ ├── functions.py │ │ ├── health.py │ │ ├── linked_accounts.py │ │ ├── projects.py │ │ └── webhooks.py │ │ ├── security_credentials_manager.py │ │ ├── sentry.py │ │ └── tests │ │ ├── __init__.py │ │ ├── app_connectors │ │ ├── __init__.py │ │ ├── integration │ │ │ ├── __init__.py │ │ │ └── agent_secrets_manager │ │ │ │ ├── __init__.py │ │ │ │ ├── conftest.py │ │ │ │ └── test_agent_secrets_manager.py │ │ └── unit │ │ │ ├── __init__.py │ │ │ └── test_agent_secrets_manager.py │ │ ├── conftest.py │ │ ├── crud │ │ └── custom_sql_types │ │ │ ├── test_encrypted_security_credentials.py │ │ │ └── test_encrypted_security_schemes.py │ │ ├── dummy_apps │ │ ├── aci_test │ │ │ ├── app.json │ │ │ └── functions.json │ │ ├── github │ │ │ ├── app.json │ │ │ └── functions.json │ │ ├── google │ │ │ ├── app.json │ │ │ └── functions.json │ │ └── mock_app_connector │ │ │ ├── app.json │ │ │ └── functions.json │ │ ├── helper.py │ │ ├── routes │ │ ├── analytics │ │ │ └── test_analytics.py │ │ ├── app_configurations │ │ │ ├── conftest.py │ │ │ ├── test_app_configurations_add.py │ │ │ ├── test_app_configurations_delete.py │ │ │ ├── test_app_configurations_get.py │ │ │ ├── test_app_configurations_list.py │ │ │ └── test_app_configurations_update.py │ │ ├── apps │ │ │ ├── test_apps.py │ │ │ ├── test_apps_get.py │ │ │ └── test_apps_list.py │ │ ├── functions │ │ │ ├── test_functions_execute.py │ │ │ ├── test_functions_execute_mock_app_connector_with_no_auth_account.py │ │ │ ├── test_functions_execute_mock_app_connector_with_oauth2_account.py │ │ │ ├── test_functions_execute_with_api_key_account.py │ │ │ ├── test_functions_execute_with_custom_instructions.py │ │ │ ├── test_functions_execute_with_oauth2_account.py │ │ │ ├── test_functions_get_definition.py │ │ │ ├── test_functions_list.py │ │ │ └── test_functions_search.py │ │ ├── health │ │ │ └── test_health.py │ │ ├── linked_acounts │ │ │ ├── test_accounts_delete.py │ │ │ ├── test_accounts_get.py │ │ │ ├── test_accounts_link_api_key.py │ │ │ ├── test_accounts_link_default.py │ │ │ ├── test_accounts_link_no_auth.py │ │ │ ├── test_accounts_link_oauth2.py │ │ │ ├── test_accounts_list.py │ │ │ ├── test_accounts_quota.py │ │ │ └── test_accounts_update.py │ │ └── projects │ │ │ ├── test_projects.py │ │ │ └── test_projects_agents.py │ │ └── security │ │ ├── test_api_key.py │ │ ├── test_quota_limit.py │ │ └── test_rate_limiting.py ├── alembic.ini ├── apps │ ├── accredible │ │ ├── app.json │ │ └── functions.json │ ├── active_campaign │ │ ├── app.json │ │ └── functions.json │ ├── aero_workflow │ │ ├── app.json │ │ └── functions.json │ ├── agent_mail │ │ ├── app.json │ │ └── functions.json │ ├── agent_secrets_manager │ │ ├── app.json │ │ └── functions.json │ ├── aidbase │ │ ├── app.json │ │ └── functions.json │ ├── airtable │ │ ├── app.json │ │ └── functions.json │ ├── akkio │ │ ├── app.json │ │ └── functions.json │ ├── all_images │ │ ├── app.json │ │ └── functions.json │ ├── anchor_browser │ │ ├── app.json │ │ └── functions.json │ ├── apaleo │ │ ├── app.json │ │ └── functions.json │ ├── api_template │ │ ├── app.json │ │ └── functions.json │ ├── arxiv │ │ ├── app.json │ │ └── functions.json │ ├── asana │ │ ├── app.json │ │ └── functions.json │ ├── baidu_map │ │ ├── app.json │ │ └── functions.json │ ├── baserow │ │ ├── app.json │ │ └── functions.json │ ├── brave_search │ │ ├── app.json │ │ └── functions.json │ ├── breezy │ │ ├── app.json │ │ └── functions.json │ ├── browserbase │ │ ├── app.json │ │ └── functions.json │ ├── cal │ │ ├── app.json │ │ └── functions.json │ ├── calendly │ │ ├── app.json │ │ └── functions.json │ ├── clickup │ │ ├── app.json │ │ └── functions.json │ ├── cloudflare │ │ ├── app.json │ │ └── functions.json │ ├── coda │ │ ├── app.json │ │ └── functions.json │ ├── cognito_forms │ │ ├── app.json │ │ └── functions.json │ ├── coin_gecko │ │ ├── app.json │ │ └── functions.json │ ├── coinmarketcap │ │ ├── app.json │ │ └── functions.json │ ├── daytona │ │ ├── app.json │ │ └── functions.json │ ├── dexscreener │ │ ├── app.json │ │ └── functions.json │ ├── dify │ │ ├── app.json │ │ └── functions.json │ ├── discord │ │ ├── app.json │ │ └── functions.json │ ├── e2b │ │ ├── app.json │ │ └── functions.json │ ├── eleven_labs │ │ ├── app.json │ │ └── functions.json │ ├── etherscan │ │ ├── app.json │ │ └── functions.json │ ├── exa_ai │ │ ├── app.json │ │ └── functions.json │ ├── factorialhr │ │ ├── app.json │ │ └── functions.json │ ├── feishu │ │ ├── app.json │ │ └── functions.json │ ├── figma │ │ ├── app.json │ │ └── functions.json │ ├── firecrawl │ │ ├── app.json │ │ └── functions.json │ ├── fireflies │ │ ├── app.json │ │ └── functions.json │ ├── github │ │ ├── app.json │ │ └── functions.json │ ├── gmail │ │ ├── app.json │ │ └── functions.json │ ├── goco │ │ ├── app.json │ │ └── functions.json │ ├── google_analytics_admin │ │ ├── app.json │ │ └── functions.json │ ├── google_calendar │ │ ├── app.json │ │ └── functions.json │ ├── google_docs │ │ ├── app.json │ │ └── functions.json │ ├── google_maps │ │ ├── app.json │ │ └── functions.json │ ├── google_sheets │ │ ├── app.json │ │ └── functions.json │ ├── google_tasks │ │ ├── app.json │ │ └── functions.json │ ├── hackernews │ │ ├── app.json │ │ └── functions.json │ ├── holded │ │ ├── app.json │ │ └── functions.json │ ├── lmnt │ │ ├── app.json │ │ └── functions.json │ ├── neon │ │ ├── app.json │ │ └── functions.json │ ├── notion │ │ ├── app.json │ │ └── functions.json │ ├── notte │ │ ├── app.json │ │ └── functions.json │ ├── one_page_crm │ │ ├── app.json │ │ └── functions.json │ ├── one_signal │ │ ├── app.json │ │ └── functions.json │ ├── open_weather_map │ │ ├── app.json │ │ └── functions.json │ ├── paddle │ │ ├── app.json │ │ └── functions.json │ ├── posthog │ │ ├── app.json │ │ └── functions.json │ ├── reddit │ │ ├── app.json │ │ └── functions.json │ ├── resend │ │ ├── app.json │ │ └── functions.json │ ├── rocketlane │ │ ├── app.json │ │ └── functions.json │ ├── rossum │ │ ├── app.json │ │ └── functions.json │ ├── scrapybara │ │ ├── app.json │ │ └── functions.json │ ├── sendgrid │ │ ├── app.json │ │ └── functions.json │ ├── sentry │ │ ├── app.json │ │ └── functions.json │ ├── serpapi │ │ ├── app.json │ │ └── functions.json │ ├── share_point │ │ ├── app.json │ │ └── functions.json │ ├── slack │ │ ├── app.json │ │ └── functions.json │ ├── solscan │ │ ├── app.json │ │ └── functions.json │ ├── steel │ │ ├── app.json │ │ └── functions.json │ ├── supabase │ │ ├── app.json │ │ └── functions.json │ ├── tavily │ │ ├── app.json │ │ └── functions.json │ ├── tines │ │ ├── app.json │ │ └── functions.json │ ├── typefully │ │ ├── app.json │ │ └── functions.json │ ├── ultra_msg │ │ ├── app.json │ │ └── functions.json │ ├── vercel │ │ ├── app.json │ │ └── functions.json │ ├── wrike │ │ ├── app.json │ │ └── functions.json │ ├── youtube │ │ ├── app.json │ │ └── functions.json │ ├── zenrows │ │ ├── app.json │ │ └── functions.json │ └── zoho_desk │ │ ├── app.json │ │ └── functions.json ├── compose.ci.yml ├── compose.yml ├── deployment │ ├── README.md │ ├── app.py │ ├── cdk.json │ ├── provision │ │ ├── __init__.py │ │ └── provision_stack.py │ └── tests │ │ ├── __init__.py │ │ └── unit │ │ ├── __init__.py │ │ └── test_provision_stack.py ├── evals │ ├── __init__.py │ ├── evaluation_pipeline.py │ ├── intent_prompts.py │ ├── search_evaluator.py │ └── synthetic_intent_generator.py ├── images │ └── propelauth-switch-to-local.png ├── mock │ ├── propelauth_fastapi_mock.py │ └── propelauth_mock_server.py ├── pyproject.toml ├── scripts │ ├── create-kms-encryption-key.sh │ └── seed_db.sh └── uv.lock └── frontend ├── .env.example ├── .gitattributes ├── .gitignore ├── .prettierignore ├── .prettierrc ├── README.md ├── components.json ├── eslint.config.mjs ├── next.config.ts ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── public ├── aci-architecture-intro.svg ├── aci-dev-full-logo.svg ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-dark.ico ├── favicon-light.ico ├── icon │ └── google.svg ├── site.webmanifest └── umcp-demo-thumbnail.png ├── sentry.client.config.ts ├── sentry.edge.config.ts ├── sentry.server.config.ts ├── sentryoptions.ts ├── src ├── __tests__ │ └── app │ │ ├── apps │ │ └── page.test.tsx │ │ └── project-setting │ │ └── page.test.tsx ├── app │ ├── account │ │ └── page.tsx │ ├── appconfigs │ │ ├── [appName] │ │ │ └── page.tsx │ │ └── page.tsx │ ├── apps │ │ ├── [appName] │ │ │ └── page.tsx │ │ └── page.tsx │ ├── global-error.tsx │ ├── globals.css │ ├── home │ │ └── page.tsx │ ├── layout.tsx │ ├── linked-accounts │ │ └── page.tsx │ ├── playground │ │ ├── chat-input.tsx │ │ ├── code-block.tsx │ │ ├── function-calling-result.tsx │ │ ├── function-calling.tsx │ │ ├── markdown.tsx │ │ ├── message-reasoning.tsx │ │ ├── message.tsx │ │ ├── messages.tsx │ │ ├── overview.tsx │ │ ├── page.tsx │ │ ├── playground-settings.tsx │ │ ├── setting-agent-selector.tsx │ │ ├── setting-app-selector.tsx │ │ ├── setting-function-selector.tsx │ │ ├── setting-linked-account-owner-id-selector.tsx │ │ └── use-scroll-to-bottom.ts │ ├── pricing │ │ └── page.tsx │ ├── project-setting │ │ └── page.tsx │ └── usage │ │ └── page.tsx ├── components │ ├── appconfig │ │ ├── add-account.tsx │ │ └── useAppConfigsTableColumns.tsx │ ├── apps │ │ ├── app-card-coming-soon.tsx │ │ ├── app-card.tsx │ │ ├── app-grid.tsx │ │ ├── configure-app │ │ │ ├── agent-selection-step.tsx │ │ │ ├── configure-app-step.tsx │ │ │ ├── index.tsx │ │ │ ├── linked-account-step.tsx │ │ │ └── stepper.tsx │ │ ├── function-detail.tsx │ │ ├── id-display.tsx │ │ ├── useAgentColumns.tsx │ │ └── useAppFunctionsColumns.tsx │ ├── charts │ │ ├── usage-bar-chart.tsx │ │ └── usage-pie-chart.tsx │ ├── context │ │ └── metainfo.tsx │ ├── home │ │ └── code-block.tsx │ ├── layout │ │ ├── BreadcrumbLinks.tsx │ │ ├── app-sidebar.tsx │ │ ├── footer.tsx │ │ ├── header.tsx │ │ └── project-selector.tsx │ ├── linkedaccount │ │ └── linked-account-details.tsx │ ├── playground │ │ └── beta-alert.tsx │ ├── pricing │ │ └── faq.tsx │ ├── project │ │ ├── agent-instruction-filter-form.tsx │ │ ├── app-edit-form.tsx │ │ ├── create-agent-form.tsx │ │ └── useAgentsTableColumns.tsx │ ├── stats │ │ ├── stats-bar.tsx │ │ └── stats-card.tsx │ ├── ui-extensions │ │ ├── enhanced-data-table │ │ │ ├── README.md │ │ │ ├── column-filter.tsx │ │ │ ├── data-table-pagination.tsx │ │ │ ├── data-table-toolbar.tsx │ │ │ ├── data-table.tsx │ │ │ └── row-selection-column.tsx │ │ └── enhanced-switch │ │ │ └── enhanced-switch.tsx │ └── ui │ │ ├── accordion.tsx │ │ ├── alert-dialog.tsx │ │ ├── alert.tsx │ │ ├── badge.tsx │ │ ├── breadcrumb.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── chart.tsx │ │ ├── checkbox.tsx │ │ ├── command.tsx │ │ ├── dialog.tsx │ │ ├── dropdown-menu.tsx │ │ ├── form.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── pagination.tsx │ │ ├── popover.tsx │ │ ├── progress.tsx │ │ ├── scroll-area.tsx │ │ ├── select.tsx │ │ ├── separator.tsx │ │ ├── sheet.tsx │ │ ├── sidebar.tsx │ │ ├── skeleton.tsx │ │ ├── sonner.tsx │ │ ├── switch.tsx │ │ ├── table.tsx │ │ ├── tabs.tsx │ │ ├── textarea.tsx │ │ └── tooltip.tsx ├── hooks │ ├── use-agent.tsx │ ├── use-app-config.tsx │ ├── use-app.tsx │ ├── use-linked-account.tsx │ ├── use-mobile.tsx │ ├── use-subscription.tsx │ └── use-tool-execution.ts ├── instrumentation.ts ├── lib │ ├── api │ │ ├── agent.ts │ │ ├── analytics.ts │ │ ├── app.ts │ │ ├── appconfig.ts │ │ ├── appfunction.ts │ │ ├── billing.ts │ │ ├── linkedaccount.ts │ │ ├── project.ts │ │ └── util.ts │ ├── comingsoon │ │ └── comingsoon.json │ ├── store │ │ └── agent.ts │ ├── types │ │ ├── analytics.ts │ │ ├── app.ts │ │ ├── appconfig.ts │ │ ├── appfunction.ts │ │ ├── billing.ts │ │ ├── linkedaccount.ts │ │ └── project.ts │ └── utils.ts └── utils │ └── time.ts ├── tailwind.config.ts ├── tsconfig.json ├── vitest.config.mts └── vitest.setup.ts /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### 🏷️ Ticket 2 | 3 | [link the issue or ticket you are addressing in this PR here, or use the **Development** 4 | section on the right sidebar to link the issue] 5 | 6 | ### 📝 Description 7 | 8 | [Describe your changes in detail (optional if the issue you linked already contains a 9 | detail description of the change)] 10 | 11 | ### 🎥 Demo (if applicable) 12 | 13 | ### 📸 Screenshots (if applicable) 14 | 15 | ### ✅ Checklist 16 | 17 | - [ ] I have signed the [Contributor License Agreement]() (CLA) and read the [contributing guide](./../CONTRIBUTING.md) (required) 18 | - [ ] I have linked this PR to an issue or a ticket (required) 19 | - [ ] I have updated the documentation related to my change if needed 20 | - [ ] I have updated the tests accordingly (required for a bug fix or a new feature) 21 | - [ ] All checks on CI passed 22 | -------------------------------------------------------------------------------- /.github/scripts/integration_detect_changed_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Takes base SHA and head SHA as inputs 4 | BASE_SHA="$1" 5 | HEAD_SHA="$2" 6 | 7 | # Get the list of changed files, focusing on integration-related files 8 | CHANGED_FILES=$(git diff --name-only $BASE_SHA $HEAD_SHA | grep -E '^(apps)/' | grep -E '\.json$' || echo "") 9 | 10 | # Echo debugging information to stderr, not stdout 11 | # This way it won't be captured in $GITHUB_OUTPUT 12 | echo "Changed files: $CHANGED_FILES" >&2 13 | 14 | # Check if there are integration-related changes 15 | if [ -z "$CHANGED_FILES" ]; then 16 | echo "No relevant integration files changed, skipping review" >&2 17 | echo "skip=true" 18 | else 19 | echo "skip=false" 20 | fi 21 | 22 | # Output the changed files list - using proper GitHub Actions output syntax 23 | echo "changed_files< pr_content.txt -------------------------------------------------------------------------------- /.github/workflows/devportal.yml: -------------------------------------------------------------------------------- 1 | name: Dev Portal Checks 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | schedule: 9 | - cron: "0 9 * * *" 10 | 11 | jobs: 12 | ci: 13 | name: Format, Lint, and Test 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: "18" 23 | cache: "npm" 24 | cache-dependency-path: frontend/package-lock.json 25 | 26 | - name: Install dependencies 27 | working-directory: frontend 28 | run: npm ci --legacy-peer-deps 29 | 30 | - name: Check formatting 31 | working-directory: frontend 32 | run: npm run format:check 33 | 34 | - name: Run linter 35 | working-directory: frontend 36 | run: npm run lint 37 | 38 | - name: Run tests 39 | working-directory: frontend 40 | run: npm run test 41 | 42 | - name: Build 43 | working-directory: frontend 44 | env: 45 | NEXT_PUBLIC_AUTH_URL: https://8367878.propelauthtest.com 46 | run: npm run build 47 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | # General checks 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v5.0.0 5 | hooks: 6 | - id: trailing-whitespace 7 | - id: end-of-file-fixer 8 | - id: check-yaml 9 | - id: check-json 10 | - id: check-added-large-files 11 | - id: check-merge-conflict 12 | 13 | # Dev Portal checks 14 | - repo: local 15 | hooks: 16 | - id: format check 17 | name: running dev portal format check 18 | language: system 19 | entry: sh -c "cd frontend && npm run format" 20 | pass_filenames: false 21 | require_serial: true 22 | - id: lint check 23 | name: running dev portal lint check 24 | language: system 25 | entry: sh -c "cd frontend && npm run lint" 26 | pass_filenames: false 27 | require_serial: true 28 | - id: test check 29 | name: running dev portal test check 30 | language: system 31 | entry: sh -c "cd frontend && npm run test:run" 32 | pass_filenames: false 33 | require_serial: true 34 | 35 | # Backend checks 36 | - repo: local 37 | hooks: 38 | - id: format 39 | name: running backend format checks 40 | language: system 41 | entry: sh -c "cd backend && uv run ruff format ." 42 | pass_filenames: false 43 | require_serial: true 44 | - id: lint 45 | name: running backend lint checks 46 | language: system 47 | entry: sh -c "cd backend && uv run ruff check . --fix" 48 | pass_filenames: false 49 | require_serial: true 50 | - id: mypy 51 | name: running backend mypy checks 52 | language: system 53 | entry: sh -c "cd backend && uv run mypy ." 54 | pass_filenames: false 55 | require_serial: true 56 | -------------------------------------------------------------------------------- /backend/.dockerignore: -------------------------------------------------------------------------------- 1 | # custom ignores 2 | **/.env 3 | **/.env.example 4 | **/__pycache__ 5 | **/*.pyc 6 | 7 | # Python 8 | __pycache__ 9 | app.egg-info 10 | *.pyc 11 | .mypy_cache 12 | .coverage 13 | htmlcov 14 | .venv 15 | -------------------------------------------------------------------------------- /backend/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "useTabs": false, 4 | "semi": true, 5 | "singleQuote": true, 6 | "trailingComma": "es5", 7 | "bracketSpacing": true, 8 | "printWidth": 100, 9 | "arrowParens": "avoid" 10 | } 11 | -------------------------------------------------------------------------------- /backend/.python-version: -------------------------------------------------------------------------------- 1 | 3.12 2 | -------------------------------------------------------------------------------- /backend/Dockerfile.runner: -------------------------------------------------------------------------------- 1 | FROM python:3.12 2 | COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ 3 | 4 | WORKDIR /workdir 5 | 6 | COPY ./pyproject.toml ./uv.lock /workdir/ 7 | 8 | RUN uv sync --no-install-project 9 | 10 | ENV PATH="/workdir/.venv/bin:$PATH" 11 | ENV PYTHONPATH=/workdir:${PYTHONPATH} 12 | -------------------------------------------------------------------------------- /backend/Dockerfile.server: -------------------------------------------------------------------------------- 1 | FROM python:3.12 2 | COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ 3 | 4 | WORKDIR /workdir 5 | 6 | COPY ./pyproject.toml ./uv.lock /workdir/ 7 | RUN uv sync --no-dev --no-install-project 8 | 9 | ENV PATH="/workdir/.venv/bin:$PATH" 10 | ENV PYTHONPATH=/workdir:${PYTHONPATH} 11 | 12 | # .env files will be skipped by default specified in .dockerignore 13 | COPY ./aci/server /workdir/aci/server 14 | COPY ./aci/common /workdir/aci/common 15 | COPY ./aci/__init__.py /workdir/aci/__init__.py 16 | 17 | # remove unecessary or sensitive files (.env files are skipped by default specified in .dockerignore) 18 | RUN rm -rf /workdir/aci/server/tests 19 | 20 | CMD ["uvicorn", "aci.server.main:app", "--proxy-headers", "--forwarded-allow-ips=*", "--host", "0.0.0.0", "--port", "8000", "--no-access-log"] 21 | -------------------------------------------------------------------------------- /backend/aci/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/__init__.py -------------------------------------------------------------------------------- /backend/aci/alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /backend/aci/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | ${imports if imports else ""} 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = ${repr(up_revision)} 16 | down_revision: Union[str, None] = ${repr(down_revision)} 17 | branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)} 18 | depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)} 19 | 20 | 21 | def upgrade() -> None: 22 | ${upgrades if upgrades else "pass"} 23 | 24 | 25 | def downgrade() -> None: 26 | ${downgrades if downgrades else "pass"} 27 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_01_27_1657-adcfaa729f61_added_custom_instructions_to_agent_table.py: -------------------------------------------------------------------------------- 1 | """added custom instructions to agent table 2 | 3 | Revision ID: adcfaa729f61 4 | Revises: c6f47d7d2fa1 5 | Create Date: 2025-01-27 16:57:57.358842+00:00 6 | 7 | """ 8 | 9 | from typing import Sequence, Union 10 | 11 | import sqlalchemy as sa 12 | from alembic import op 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = "adcfaa729f61" 16 | down_revision: Union[str, None] = "c6f47d7d2fa1" 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.add_column("agents", sa.Column("custom_instructions", sa.JSON(), nullable=False)) 24 | # ### end Alembic commands ### 25 | 26 | 27 | def downgrade() -> None: 28 | # ### commands auto generated by Alembic - please adjust! ### 29 | op.drop_column("agents", "custom_instructions") 30 | # ### end Alembic commands ### 31 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_03_08_1922-70dd635d80d4_add_new_protocol_enum_value.py: -------------------------------------------------------------------------------- 1 | """add new protocol enum value 2 | 3 | Revision ID: 70dd635d80d4 4 | Revises: 6482e8fa201e 5 | Create Date: 2025-03-08 19:22:45.910952+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = '70dd635d80d4' 16 | down_revision: Union[str, None] = '6482e8fa201e' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # Create a new temporary enum type with the new value 23 | op.execute("ALTER TYPE protocol ADD VALUE 'CONNECTOR'") 24 | 25 | # Note: PostgreSQL allows adding values to enum types directly with the command above. 26 | # If you were using a different database, you might need a more complex migration. 27 | 28 | 29 | def downgrade() -> None: 30 | # Unfortunately, PostgreSQL doesn't provide a direct way to remove enum values 31 | # The only way would be to create a new type without the value and migrate data 32 | # This is complex and potentially dangerous, so it's often left as a no-op 33 | pass 34 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_03_10_2339-28702a5576f5_change_agent_level_app_function_acl.py: -------------------------------------------------------------------------------- 1 | """change agent level app/function acl 2 | 3 | Revision ID: 28702a5576f5 4 | Revises: 70dd635d80d4 5 | Create Date: 2025-03-10 23:39:42.611170+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | from sqlalchemy.dialects import postgresql 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = '28702a5576f5' 16 | down_revision: Union[str, None] = '70dd635d80d4' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.add_column('agents', sa.Column('allowed_apps', postgresql.ARRAY(sa.String(length=255)), nullable=False)) 24 | op.drop_column('agents', 'excluded_apps') 25 | op.drop_column('agents', 'excluded_functions') 26 | # ### end Alembic commands ### 27 | 28 | 29 | def downgrade() -> None: 30 | # ### commands auto generated by Alembic - please adjust! ### 31 | op.add_column('agents', sa.Column('excluded_functions', postgresql.ARRAY(sa.VARCHAR(length=255)), autoincrement=False, nullable=False)) 32 | op.add_column('agents', sa.Column('excluded_apps', postgresql.ARRAY(sa.VARCHAR(length=255)), autoincrement=False, nullable=False)) 33 | op.drop_column('agents', 'allowed_apps') 34 | # ### end Alembic commands ### 35 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_03_14_2000-1b82aeb7431f_create_secret_table.py: -------------------------------------------------------------------------------- 1 | """Create Secret table 2 | 3 | Revision ID: 1b82aeb7431f 4 | Revises: 949afaf258c3 5 | Create Date: 2025-03-14 20:00:46.127853+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | from sqlalchemy.dialects import postgresql 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = '1b82aeb7431f' 16 | down_revision: Union[str, None] = '949afaf258c3' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.create_table('secrets', 24 | sa.Column('id', sa.UUID(), nullable=False), 25 | sa.Column('linked_account_id', sa.UUID(), nullable=False), 26 | sa.Column('key', sa.String(length=255), nullable=False), 27 | sa.Column('value', postgresql.BYTEA(), nullable=False), 28 | sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), 29 | sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False), 30 | sa.ForeignKeyConstraint(['linked_account_id'], ['linked_accounts.id'], ), 31 | sa.PrimaryKeyConstraint('id'), 32 | sa.UniqueConstraint('linked_account_id', 'key', name='uc_linked_account_key') 33 | ) 34 | # ### end Alembic commands ### 35 | 36 | 37 | def downgrade() -> None: 38 | # ### commands auto generated by Alembic - please adjust! ### 39 | op.drop_table('secrets') 40 | # ### end Alembic commands ### 41 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_04_11_1232-7a159de1064c_add_nullable_org_id_column.py: -------------------------------------------------------------------------------- 1 | """Add nullable org_id column 2 | 3 | Revision ID: 7a159de1064c 4 | Revises: 1b82aeb7431f 5 | Create Date: 2025-04-11 12:32:20.415772+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = '7a159de1064c' 16 | down_revision: Union[str, None] = '1b82aeb7431f' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.add_column('projects', sa.Column('org_id', sa.UUID(), nullable=True)) 24 | # ### end Alembic commands ### 25 | 26 | 27 | def downgrade() -> None: 28 | # ### commands auto generated by Alembic - please adjust! ### 29 | op.drop_column('projects', 'org_id') 30 | # ### end Alembic commands ### 31 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_04_11_1236-a79cdd14460e_make_org_id_of_project_table_not_.py: -------------------------------------------------------------------------------- 1 | """Make org_id of project table not nullable 2 | 3 | Revision ID: a79cdd14460e 4 | Revises: 7a159de1064c 5 | Create Date: 2025-04-11 12:36:10.907555+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = 'a79cdd14460e' 16 | down_revision: Union[str, None] = '7a159de1064c' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.alter_column('projects', 'org_id', 24 | existing_type=sa.UUID(), 25 | nullable=False) 26 | # ### end Alembic commands ### 27 | 28 | 29 | def downgrade() -> None: 30 | # ### commands auto generated by Alembic - please adjust! ### 31 | op.alter_column('projects', 'org_id', 32 | existing_type=sa.UUID(), 33 | nullable=True) 34 | # ### end Alembic commands ### 35 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_04_11_1237-af2ecf7ca19a_drop_owner_id_column_of_project_table.py: -------------------------------------------------------------------------------- 1 | """Drop owner_id column of project table 2 | 3 | Revision ID: af2ecf7ca19a 4 | Revises: a79cdd14460e 5 | Create Date: 2025-04-11 12:37:30.824896+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = 'af2ecf7ca19a' 16 | down_revision: Union[str, None] = 'a79cdd14460e' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.drop_constraint('projects_owner_id_fkey', 'projects', type_='foreignkey') 24 | op.drop_column('projects', 'owner_id') 25 | # ### end Alembic commands ### 26 | 27 | 28 | def downgrade() -> None: 29 | # ### commands auto generated by Alembic - please adjust! ### 30 | op.add_column('projects', sa.Column('owner_id', sa.UUID(), autoincrement=False, nullable=False)) 31 | op.create_foreign_key('projects_owner_id_fkey', 'projects', 'entities', ['owner_id'], ['id']) 32 | # ### end Alembic commands ### 33 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_04_15_0929-c5978747c602_add_encrypted_key_and_key_hmac_columns_.py: -------------------------------------------------------------------------------- 1 | """Add encrypted_key and key_hmac columns for api_keys table 2 | 3 | Revision ID: c5978747c602 4 | Revises: bce2fbe6273b 5 | Create Date: 2025-04-15 09:29:41.112876+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | from aci.common.db.custom_sql_types import Key 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = 'c5978747c602' 16 | down_revision: Union[str, None] = 'bce2fbe6273b' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.add_column('api_keys', sa.Column('encrypted_key', Key(), nullable=True)) 24 | op.add_column('api_keys', sa.Column('key_hmac', sa.String(length=64), nullable=True)) 25 | op.create_unique_constraint('api_keys_encrypted_key_key', 'api_keys', ['encrypted_key']) 26 | op.create_unique_constraint('api_keys_key_hmac_key', 'api_keys', ['key_hmac']) 27 | # ### end Alembic commands ### 28 | 29 | 30 | def downgrade() -> None: 31 | # ### commands auto generated by Alembic - please adjust! ### 32 | op.drop_constraint('api_keys_encrypted_key_key', 'api_keys', type_='unique') 33 | op.drop_constraint('api_keys_key_hmac_key', 'api_keys', type_='unique') 34 | op.drop_column('api_keys', 'key_hmac') 35 | op.drop_column('api_keys', 'encrypted_key') 36 | # ### end Alembic commands ### 37 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_04_15_0930-0846452f51ac_drop_the_key_column_of_the_api_keys_.py: -------------------------------------------------------------------------------- 1 | """Drop the key column of the api_keys table 2 | 3 | Revision ID: 0846452f51ac 4 | Revises: c5978747c602 5 | Create Date: 2025-04-15 09:30:48.205741+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = '0846452f51ac' 16 | down_revision: Union[str, None] = 'c5978747c602' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.drop_constraint('api_keys_key_key', 'api_keys', type_='unique') 24 | op.drop_column('api_keys', 'key') 25 | # ### end Alembic commands ### 26 | 27 | 28 | def downgrade() -> None: 29 | # ### commands auto generated by Alembic - please adjust! ### 30 | op.add_column('api_keys', sa.Column('key', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) 31 | op.create_unique_constraint('api_keys_key_key', 'api_keys', ['key']) 32 | # ### end Alembic commands ### 33 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_04_15_0932-7ecafab6f8f9_rename_encrypted_key_column_to_key_and_.py: -------------------------------------------------------------------------------- 1 | """Rename encrypted_key column to key and make encrypted_key and key_hmac not nullable 2 | 3 | Revision ID: 7ecafab6f8f9 4 | Revises: 0846452f51ac 5 | Create Date: 2025-04-15 09:32:55.974507+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | 12 | # revision identifiers, used by Alembic. 13 | revision: str = '7ecafab6f8f9' 14 | down_revision: Union[str, None] = '0846452f51ac' 15 | branch_labels: Union[str, Sequence[str], None] = None 16 | depends_on: Union[str, Sequence[str], None] = None 17 | 18 | 19 | def upgrade() -> None: 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.alter_column('api_keys', 'encrypted_key', new_column_name='key', nullable=False) 22 | op.alter_column('api_keys', 'key_hmac', nullable=False) 23 | 24 | # ### end Alembic commands ### 25 | 26 | 27 | def downgrade() -> None: 28 | # ### commands auto generated by Alembic - please adjust! ### 29 | op.alter_column('api_keys', 'key', new_column_name='encrypted_key', nullable=True) 30 | op.alter_column('api_keys', 'key_hmac', nullable=True) 31 | # ### end Alembic commands ### 32 | -------------------------------------------------------------------------------- /backend/aci/alembic/versions/2025_04_29_1220-ce439f017e25_add_last_used_at_to_linked_accounts.py: -------------------------------------------------------------------------------- 1 | """add last_used_at to linked_accounts 2 | 3 | Revision ID: ce439f017e25 4 | Revises: 7ecafab6f8f9 5 | Create Date: 2025-04-29 12:20:50.965618+00:00 6 | 7 | """ 8 | from typing import Sequence, Union 9 | 10 | from alembic import op 11 | import sqlalchemy as sa 12 | 13 | 14 | # revision identifiers, used by Alembic. 15 | revision: str = 'ce439f017e25' 16 | down_revision: Union[str, None] = '7ecafab6f8f9' 17 | branch_labels: Union[str, Sequence[str], None] = None 18 | depends_on: Union[str, Sequence[str], None] = None 19 | 20 | 21 | def upgrade() -> None: 22 | # ### commands auto generated by Alembic - please adjust! ### 23 | op.add_column('linked_accounts', sa.Column('last_used_at', sa.DateTime(), nullable=True)) 24 | # ### end Alembic commands ### 25 | 26 | 27 | def downgrade() -> None: 28 | # ### commands auto generated by Alembic - please adjust! ### 29 | op.drop_column('linked_accounts', 'last_used_at') 30 | # ### end Alembic commands ### 31 | -------------------------------------------------------------------------------- /backend/aci/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/cli/__init__.py -------------------------------------------------------------------------------- /backend/aci/cli/__main__.py: -------------------------------------------------------------------------------- 1 | from aci.cli.aci import cli 2 | 3 | if __name__ == "__main__": 4 | cli() 5 | -------------------------------------------------------------------------------- /backend/aci/cli/aci.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | from aci.cli.commands import ( 4 | billing, 5 | create_agent, 6 | create_project, 7 | create_random_api_key, 8 | delete_app, 9 | fuzzy_test_function_execution, 10 | get_app, 11 | rename_app, 12 | update_agent, 13 | upsert_app, 14 | upsert_functions, 15 | ) 16 | from aci.common.logging_setup import setup_logging 17 | 18 | 19 | @click.group(context_settings={"help_option_names": ["-h", "--help"]}) 20 | def cli() -> None: 21 | """AIPO CLI Tool""" 22 | setup_logging() 23 | 24 | 25 | # Add commands to the group 26 | cli.add_command(create_project.create_project) 27 | cli.add_command(create_agent.create_agent) 28 | cli.add_command(update_agent.update_agent) 29 | cli.add_command(upsert_app.upsert_app) 30 | cli.add_command(get_app.get_app) 31 | cli.add_command(rename_app.rename_app) 32 | cli.add_command(delete_app.delete_app) 33 | cli.add_command(upsert_functions.upsert_functions) 34 | cli.add_command(create_random_api_key.create_random_api_key) 35 | cli.add_command(fuzzy_test_function_execution.fuzzy_test_function_execution) 36 | cli.add_command(billing.populate_subscription_plans) 37 | 38 | if __name__ == "__main__": 39 | cli() 40 | -------------------------------------------------------------------------------- /backend/aci/cli/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/cli/commands/__init__.py -------------------------------------------------------------------------------- /backend/aci/cli/commands/get_app.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | import click 4 | from rich.console import Console 5 | from rich.syntax import Syntax 6 | 7 | from aci.cli import config 8 | from aci.common import utils 9 | from aci.common.db import crud 10 | 11 | console = Console() 12 | 13 | 14 | @click.command() 15 | @click.option( 16 | "--app-name", 17 | "app_name", 18 | required=True, 19 | help="Name of the app to retrieve", 20 | ) 21 | def get_app( 22 | app_name: str, 23 | ) -> None: 24 | """ 25 | Get an app by name from the database. 26 | """ 27 | with utils.create_db_session(config.DB_FULL_URL) as db_session: 28 | app = crud.apps.get_app( 29 | db_session, 30 | app_name, 31 | public_only=False, 32 | active_only=False, 33 | ) 34 | 35 | if app is None: 36 | console.rule(f"[bold red]App '{app_name}' not found[/bold red]") 37 | return 38 | 39 | console.rule(f"[bold green]App: {app.name}[/bold green]") 40 | 41 | # print without excluded fields 42 | excluded_fields = ["functions", "_sa_instance_state"] 43 | app_dict = {} 44 | for key, value in vars(app).items(): 45 | if key not in excluded_fields: 46 | app_dict[key] = value 47 | 48 | # Add function count 49 | app_dict["function_count"] = len(app.functions) if hasattr(app, "functions") else 0 50 | 51 | # Convert to JSON string with nice formatting 52 | json_str = json.dumps(app_dict, indent=2, default=str) 53 | 54 | # Print with syntax highlighting 55 | console.print(Syntax(json_str, "json", theme="monokai")) 56 | -------------------------------------------------------------------------------- /backend/aci/cli/config.py: -------------------------------------------------------------------------------- 1 | from dotenv import load_dotenv 2 | 3 | from aci.common.utils import check_and_get_env_variable, construct_db_url 4 | 5 | load_dotenv() 6 | 7 | OPENAI_API_KEY = check_and_get_env_variable("CLI_OPENAI_API_KEY") 8 | OPENAI_EMBEDDING_MODEL = check_and_get_env_variable("CLI_OPENAI_EMBEDDING_MODEL") 9 | OPENAI_EMBEDDING_DIMENSION = int(check_and_get_env_variable("CLI_OPENAI_EMBEDDING_DIMENSION")) 10 | DB_SCHEME = check_and_get_env_variable("CLI_DB_SCHEME") 11 | DB_USER = check_and_get_env_variable("CLI_DB_USER") 12 | DB_PASSWORD = check_and_get_env_variable("CLI_DB_PASSWORD") 13 | DB_HOST = check_and_get_env_variable("CLI_DB_HOST") 14 | DB_PORT = check_and_get_env_variable("CLI_DB_PORT") 15 | DB_NAME = check_and_get_env_variable("CLI_DB_NAME") 16 | DB_FULL_URL = construct_db_url(DB_SCHEME, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_NAME) 17 | SERVER_URL = check_and_get_env_variable("CLI_SERVER_URL") 18 | -------------------------------------------------------------------------------- /backend/aci/cli/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/cli/tests/__init__.py -------------------------------------------------------------------------------- /backend/aci/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/common/__init__.py -------------------------------------------------------------------------------- /backend/aci/common/config.py: -------------------------------------------------------------------------------- 1 | from aci.common.utils import check_and_get_env_variable 2 | 3 | AWS_REGION = check_and_get_env_variable("COMMON_AWS_REGION") 4 | AWS_ENDPOINT_URL = check_and_get_env_variable("COMMON_AWS_ENDPOINT_URL") 5 | KEY_ENCRYPTION_KEY_ARN = check_and_get_env_variable("COMMON_KEY_ENCRYPTION_KEY_ARN") 6 | API_KEY_HASHING_SECRET = check_and_get_env_variable("COMMON_API_KEY_HASHING_SECRET") 7 | -------------------------------------------------------------------------------- /backend/aci/common/db/crud/__init__.py: -------------------------------------------------------------------------------- 1 | from . import ( 2 | app_configurations, 3 | apps, 4 | functions, 5 | linked_accounts, 6 | plans, 7 | processed_stripe_event, 8 | projects, 9 | secret, 10 | subscriptions, 11 | ) 12 | 13 | __all__ = [ 14 | "app_configurations", 15 | "apps", 16 | "functions", 17 | "linked_accounts", 18 | "plans", 19 | "processed_stripe_event", 20 | "projects", 21 | "secret", 22 | "subscriptions", 23 | ] 24 | -------------------------------------------------------------------------------- /backend/aci/common/db/crud/processed_stripe_event.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import select 2 | from sqlalchemy.orm import Session 3 | 4 | from aci.common.db.sql_models import ProcessedStripeEvent 5 | from aci.common.logging_setup import get_logger 6 | 7 | logger = get_logger(__name__) 8 | 9 | 10 | def record_processed_event(db_session: Session, event_id: str) -> ProcessedStripeEvent: 11 | """ 12 | Create a new processed Stripe event record. 13 | 14 | Args: 15 | db_session: The database session. 16 | event_id: The Stripe event ID that was processed. 17 | 18 | Returns: 19 | The created ProcessedStripeEvent record. 20 | """ 21 | processed_event = ProcessedStripeEvent(event_id=event_id) 22 | db_session.add(processed_event) 23 | db_session.flush() 24 | db_session.refresh(processed_event) 25 | return processed_event 26 | 27 | 28 | def is_event_processed(db_session: Session, event_id: str) -> bool: 29 | """ 30 | Check if a Stripe event has already been processed. 31 | 32 | Args: 33 | db_session: The database session. 34 | event_id: The Stripe event ID to check. 35 | 36 | Returns: 37 | True if the event has already been processed, False otherwise. 38 | """ 39 | statement = select(ProcessedStripeEvent).filter_by(event_id=event_id) 40 | result = db_session.execute(statement).scalar_one_or_none() 41 | return result is not None 42 | -------------------------------------------------------------------------------- /backend/aci/common/schemas/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/common/schemas/__init__.py -------------------------------------------------------------------------------- /backend/aci/common/schemas/agent.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from typing import Annotated 3 | from uuid import UUID 4 | 5 | from pydantic import BaseModel, BeforeValidator, ConfigDict, Field 6 | 7 | from aci.common.schemas.apikey import APIKeyPublic 8 | 9 | MAX_INSTRUCTION_LENGTH = 5000 10 | 11 | 12 | # TODO: add unit tests 13 | # Custom type with validation 14 | def validate_instruction(v: str) -> str: 15 | if not v.strip(): 16 | raise ValueError("Instructions cannot be empty strings") 17 | if len(v) > MAX_INSTRUCTION_LENGTH: 18 | raise ValueError(f"Instructions cannot be longer than {MAX_INSTRUCTION_LENGTH} characters") 19 | return v 20 | 21 | 22 | ValidInstruction = Annotated[str, BeforeValidator(validate_instruction)] 23 | 24 | 25 | # TODO: validate when creating or updating agent that allowed_apps only contains apps that are configured 26 | # for the project 27 | class AgentCreate(BaseModel): 28 | name: str 29 | description: str 30 | allowed_apps: list[str] = [] 31 | custom_instructions: dict[str, ValidInstruction] = Field(default_factory=dict) 32 | 33 | 34 | class AgentUpdate(BaseModel): 35 | name: str | None = None 36 | description: str | None = None 37 | allowed_apps: list[str] | None = None 38 | custom_instructions: dict[str, ValidInstruction] | None = None 39 | 40 | 41 | class AgentPublic(BaseModel): 42 | id: UUID 43 | project_id: UUID 44 | name: str 45 | description: str 46 | allowed_apps: list[str] = [] 47 | custom_instructions: dict[str, ValidInstruction] = Field(default_factory=dict) 48 | 49 | created_at: datetime 50 | updated_at: datetime 51 | 52 | api_keys: list[APIKeyPublic] 53 | 54 | model_config = ConfigDict(from_attributes=True) 55 | -------------------------------------------------------------------------------- /backend/aci/common/schemas/analytics.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, ConfigDict 2 | 3 | 4 | class DistributionDatapoint(BaseModel): 5 | """Model for distribution data visualization.""" 6 | 7 | name: str 8 | value: float 9 | 10 | 11 | class TimeSeriesDatapoint(BaseModel): 12 | """Model for time series data visualization.""" 13 | 14 | date: str 15 | model_config = ConfigDict(extra="allow") 16 | -------------------------------------------------------------------------------- /backend/aci/common/schemas/apikey.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from uuid import UUID 3 | 4 | from pydantic import BaseModel, ConfigDict 5 | 6 | from aci.common.enums import APIKeyStatus 7 | 8 | 9 | class APIKeyPublic(BaseModel): 10 | id: UUID 11 | key: str 12 | agent_id: UUID 13 | status: APIKeyStatus 14 | 15 | created_at: datetime 16 | updated_at: datetime 17 | 18 | model_config = ConfigDict(from_attributes=True) 19 | -------------------------------------------------------------------------------- /backend/aci/common/schemas/app_connectors/agent_secrets_manager.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class DomainCredential(BaseModel): 5 | username: str 6 | password: str 7 | domain: str 8 | 9 | 10 | class SecretValue(BaseModel): 11 | username: str 12 | password: str 13 | -------------------------------------------------------------------------------- /backend/aci/common/schemas/plans.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | 4 | class PlanFeatures(BaseModel): 5 | linked_accounts: int 6 | api_calls_monthly: int 7 | agent_credentials: int 8 | developer_seats: int 9 | custom_oauth: bool 10 | log_retention_days: int 11 | 12 | 13 | class PlanUpdate(BaseModel, extra="forbid"): 14 | stripe_product_id: str | None = Field(None) 15 | stripe_monthly_price_id: str | None = Field(None) 16 | stripe_yearly_price_id: str | None = Field(None) 17 | features: PlanFeatures | None = Field(None) 18 | is_public: bool | None = Field(None) 19 | -------------------------------------------------------------------------------- /backend/aci/common/schemas/project.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from uuid import UUID 3 | 4 | from pydantic import BaseModel, ConfigDict, Field 5 | 6 | from aci.common.enums import Visibility 7 | from aci.common.schemas.agent import AgentPublic 8 | 9 | 10 | class ProjectCreate(BaseModel): 11 | """Project can be created under a user or an organization.""" 12 | 13 | name: str 14 | org_id: UUID = Field( 15 | description="Organization ID if project is to be created under an organization", 16 | ) 17 | 18 | 19 | class ProjectPublic(BaseModel): 20 | id: UUID 21 | org_id: UUID 22 | name: str 23 | visibility_access: Visibility 24 | daily_quota_used: int 25 | daily_quota_reset_at: datetime 26 | total_quota_used: int 27 | 28 | created_at: datetime 29 | updated_at: datetime 30 | 31 | agents: list[AgentPublic] 32 | 33 | model_config = ConfigDict(from_attributes=True) 34 | -------------------------------------------------------------------------------- /backend/aci/common/schemas/secret.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | 4 | class SecretCreate(BaseModel): 5 | key: str 6 | value: bytes 7 | 8 | 9 | class SecretUpdate(BaseModel): 10 | value: bytes 11 | -------------------------------------------------------------------------------- /backend/aci/common/schemas/subscription.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from uuid import UUID 3 | 4 | from pydantic import BaseModel 5 | 6 | from aci.common.enums import StripeSubscriptionInterval, StripeSubscriptionStatus 7 | 8 | 9 | class SubscriptionBase(BaseModel): 10 | org_id: UUID 11 | plan_id: UUID 12 | stripe_customer_id: str 13 | stripe_subscription_id: str 14 | status: StripeSubscriptionStatus 15 | interval: StripeSubscriptionInterval 16 | current_period_end: datetime 17 | cancel_at_period_end: bool 18 | 19 | 20 | class SubscriptionCreate(SubscriptionBase): 21 | pass 22 | 23 | 24 | class SubscriptionUpdate(BaseModel): 25 | plan_id: UUID 26 | status: StripeSubscriptionStatus 27 | stripe_customer_id: str 28 | interval: StripeSubscriptionInterval 29 | current_period_end: datetime 30 | cancel_at_period_end: bool 31 | 32 | 33 | class SubscriptionPublic(BaseModel): 34 | plan: str 35 | status: StripeSubscriptionStatus 36 | 37 | 38 | class StripeSubscriptionDetails(BaseModel): 39 | stripe_subscription_id: str 40 | stripe_customer_id: str 41 | status: StripeSubscriptionStatus 42 | current_period_end: datetime 43 | cancel_at_period_end: bool 44 | stripe_price_id: str 45 | interval: StripeSubscriptionInterval 46 | 47 | 48 | class StripeSubscriptionMetadata(BaseModel): 49 | org_id: UUID 50 | checkout_user_id: str 51 | checkout_user_email: str 52 | 53 | 54 | class StripeCheckoutSessionCreate(BaseModel): 55 | plan_name: str 56 | interval: StripeSubscriptionInterval 57 | -------------------------------------------------------------------------------- /backend/aci/common/test_utils.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from collections.abc import Generator 3 | 4 | from sqlalchemy.orm import Session 5 | 6 | from aci.common import utils 7 | from aci.common.db.sql_models import Base 8 | from aci.server import config 9 | 10 | logger = logging.getLogger(__name__) 11 | 12 | 13 | def clear_database(db_session: Session) -> None: 14 | """ 15 | Clear all tables in the database except alembic_version. 16 | """ 17 | for table in reversed(Base.metadata.sorted_tables): 18 | if table.name != "alembic_version" and db_session.query(table).count() > 0: 19 | logger.debug(f"Deleting all records from table {table.name}") 20 | db_session.execute(table.delete()) 21 | db_session.commit() 22 | 23 | 24 | def create_test_db_session() -> Generator[Session, None, None]: 25 | """ 26 | Create a database session for testing. 27 | Ensures we're using the test database. 28 | Each test gets its own database session for better isolation. 29 | """ 30 | assert config.DB_HOST == "test-db", "Must use test-db for tests" 31 | assert "test" in config.DB_FULL_URL.lower(), "Database URL must contain 'test' for safety" 32 | 33 | with utils.create_db_session(config.DB_FULL_URL) as session: 34 | yield session 35 | -------------------------------------------------------------------------------- /backend/aci/common/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/common/tests/__init__.py -------------------------------------------------------------------------------- /backend/aci/common/tests/crud/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/common/tests/crud/__init__.py -------------------------------------------------------------------------------- /backend/aci/common/validators/__init__.py: -------------------------------------------------------------------------------- 1 | from . import security_scheme 2 | 3 | __all__ = [ 4 | "security_scheme", 5 | ] 6 | -------------------------------------------------------------------------------- /backend/aci/common/validators/security_scheme.py: -------------------------------------------------------------------------------- 1 | from aci.common.enums import SecurityScheme 2 | from aci.common.logging_setup import get_logger 3 | from aci.common.schemas.security_scheme import ( 4 | APIKeySchemeCredentials, 5 | NoAuthSchemeCredentials, 6 | OAuth2SchemeCredentials, 7 | ) 8 | 9 | logger = get_logger(__name__) 10 | 11 | 12 | def validate_scheme_and_credentials_type_match( 13 | security_scheme: SecurityScheme, 14 | security_credentials: OAuth2SchemeCredentials 15 | | APIKeySchemeCredentials 16 | | NoAuthSchemeCredentials, 17 | ) -> None: 18 | scheme_to_credentials = { 19 | SecurityScheme.OAUTH2: OAuth2SchemeCredentials, 20 | SecurityScheme.API_KEY: APIKeySchemeCredentials, 21 | SecurityScheme.NO_AUTH: NoAuthSchemeCredentials, 22 | } 23 | 24 | expected_type = scheme_to_credentials.get(security_scheme) 25 | if expected_type is None: 26 | logger.error( 27 | "Unsupported security scheme", 28 | extra={"scheme": security_scheme, "credentials_type": type(security_credentials)}, 29 | ) 30 | raise ValueError(f"Unsupported security scheme: {security_scheme}") 31 | 32 | if not isinstance(security_credentials, expected_type): 33 | logger.error( 34 | "Scheme and credentials type mismatch", 35 | extra={"scheme": security_scheme, "credentials_type": type(security_credentials)}, 36 | ) 37 | raise ValueError( 38 | f"Invalid security credentials type: {type(security_credentials)} for scheme: {security_scheme}" 39 | ) 40 | -------------------------------------------------------------------------------- /backend/aci/server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/agent/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/agent/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/agent/types.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | 4 | class ToolInvocation(BaseModel): 5 | tool_call_id: str = Field(alias="toolCallId") 6 | tool_name: str = Field(alias="toolName") 7 | step: int 8 | state: str | None = None 9 | args: dict | None = None 10 | result: dict | list[dict] | None = None 11 | 12 | 13 | class ClientMessage(BaseModel): 14 | role: str 15 | content: str 16 | tool_invocations: list[ToolInvocation] | None = Field(default=None, alias="toolInvocations") 17 | -------------------------------------------------------------------------------- /backend/aci/server/app_connectors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/app_connectors/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/app_connectors/e2b.py: -------------------------------------------------------------------------------- 1 | from typing import Any, override 2 | 3 | from e2b_code_interpreter import Sandbox 4 | 5 | from aci.common.db.sql_models import LinkedAccount 6 | from aci.common.logging_setup import get_logger 7 | from aci.common.schemas.security_scheme import ( 8 | APIKeyScheme, 9 | APIKeySchemeCredentials, 10 | ) 11 | from aci.server.app_connectors.base import AppConnectorBase 12 | 13 | logger = get_logger(__name__) 14 | 15 | 16 | class E2b(AppConnectorBase): 17 | """ 18 | E2B.dev Sandbox Connector using Code Interpreter. 19 | """ 20 | 21 | def __init__( 22 | self, 23 | linked_account: LinkedAccount, 24 | security_scheme: APIKeyScheme, 25 | security_credentials: APIKeySchemeCredentials, 26 | ): 27 | super().__init__(linked_account, security_scheme, security_credentials) 28 | self.api_key = security_credentials.secret_key 29 | 30 | @override 31 | def _before_execute(self) -> None: 32 | pass 33 | 34 | def run_code( 35 | self, 36 | code: str, 37 | ) -> dict[str, Any]: 38 | """ 39 | Execute code in E2B sandbox and return the result. 40 | """ 41 | with Sandbox(api_key=self.api_key) as sandbox: 42 | execution = sandbox.run_code(code) 43 | return {"text": execution.text} 44 | -------------------------------------------------------------------------------- /backend/aci/server/app_connectors/vercel.py: -------------------------------------------------------------------------------- 1 | from typing import Any, override 2 | 3 | from aci.common.db.sql_models import LinkedAccount 4 | from aci.common.logging_setup import get_logger 5 | from aci.common.schemas.security_scheme import ( 6 | APIKeyScheme, 7 | APIKeySchemeCredentials, 8 | ) 9 | from aci.server.app_connectors.base import AppConnectorBase 10 | 11 | logger = get_logger(__name__) 12 | 13 | 14 | class Vercel(AppConnectorBase): 15 | def __init__( 16 | self, 17 | linked_account: LinkedAccount, 18 | security_scheme: APIKeyScheme, 19 | security_credentials: APIKeySchemeCredentials, 20 | ): 21 | super().__init__(linked_account, security_scheme, security_credentials) 22 | self.api_key = security_credentials.secret_key 23 | 24 | @override 25 | def _before_execute(self) -> None: 26 | pass 27 | 28 | def get_url_to_install_vercel_app_in_github(self) -> dict[str, Any]: 29 | """ 30 | Get the URL to install the Vercel app in a GitHub repository. 31 | """ 32 | return { 33 | "url": "https://github.com/apps/vercel/installations/select_target", 34 | "description": "Asks the user to use this URL to install the Vercel app in their GitHub account.", 35 | } 36 | -------------------------------------------------------------------------------- /backend/aci/server/context.py: -------------------------------------------------------------------------------- 1 | import contextvars 2 | 3 | request_id_ctx_var = contextvars.ContextVar[str | None]("request_id", default="unknown") 4 | agent_id_ctx_var = contextvars.ContextVar[str | None]("agent_id", default="unknown") 5 | api_key_id_ctx_var = contextvars.ContextVar[str | None]("api_key_id", default="unknown") 6 | project_id_ctx_var = contextvars.ContextVar[str | None]("project_id", default="unknown") 7 | org_id_ctx_var = contextvars.ContextVar[str | None]("org_id", default="unknown") 8 | -------------------------------------------------------------------------------- /backend/aci/server/dependency_check.py: -------------------------------------------------------------------------------- 1 | from aci.common.encryption import decrypt, encrypt 2 | from aci.common.exceptions import DependencyCheckError 3 | 4 | 5 | def check_aws_kms_dependency() -> None: 6 | check_data = b"start up dependency check" 7 | 8 | encrypted_data = encrypt(check_data) 9 | decrypted_data = decrypt(encrypted_data) 10 | 11 | if check_data != decrypted_data: 12 | raise DependencyCheckError( 13 | f"Encryption/decryption using AWS KMS failed: original data '{check_data!r}'" 14 | f"does not match decrypted result '{decrypted_data!r}'" 15 | ) 16 | 17 | 18 | def check_dependencies() -> None: 19 | check_aws_kms_dependency() 20 | -------------------------------------------------------------------------------- /backend/aci/server/function_executors/__init__.py: -------------------------------------------------------------------------------- 1 | from aci.common.db.sql_models import LinkedAccount 2 | from aci.common.enums import Protocol, SecurityScheme 3 | from aci.common.logging_setup import get_logger 4 | from aci.server.function_executors.base_executor import FunctionExecutor 5 | from aci.server.function_executors.connector_function_executor import ( 6 | ConnectorFunctionExecutor, 7 | ) 8 | from aci.server.function_executors.rest_api_key_function_executor import ( 9 | RestAPIKeyFunctionExecutor, 10 | ) 11 | from aci.server.function_executors.rest_no_auth_function_executor import ( 12 | RestNoAuthFunctionExecutor, 13 | ) 14 | from aci.server.function_executors.rest_oauth2_function_executor import ( 15 | RestOAuth2FunctionExecutor, 16 | ) 17 | 18 | logger = get_logger(__name__) 19 | 20 | 21 | def get_executor(protocol: Protocol, linked_account: LinkedAccount) -> FunctionExecutor: 22 | match protocol, linked_account.security_scheme: 23 | case Protocol.REST, SecurityScheme.API_KEY: 24 | return RestAPIKeyFunctionExecutor(linked_account) 25 | case Protocol.REST, SecurityScheme.OAUTH2: 26 | return RestOAuth2FunctionExecutor(linked_account) 27 | case Protocol.REST, SecurityScheme.NO_AUTH: 28 | return RestNoAuthFunctionExecutor(linked_account) 29 | case Protocol.CONNECTOR, _: 30 | return ConnectorFunctionExecutor(linked_account) 31 | case _: 32 | raise ValueError("Unsupported protocol or security scheme") 33 | 34 | 35 | __all__ = ["FunctionExecutor", "get_executor"] 36 | -------------------------------------------------------------------------------- /backend/aci/server/function_executors/rest_no_auth_function_executor.py: -------------------------------------------------------------------------------- 1 | from typing import override 2 | 3 | from aci.common.schemas.security_scheme import NoAuthScheme, NoAuthSchemeCredentials 4 | from aci.server.function_executors.rest_function_executor import RestFunctionExecutor 5 | 6 | 7 | class RestNoAuthFunctionExecutor(RestFunctionExecutor[NoAuthScheme, NoAuthSchemeCredentials]): 8 | """ 9 | Function executor for REST functions that don't require authentication. 10 | """ 11 | 12 | @override 13 | def _inject_credentials( 14 | self, 15 | security_scheme: NoAuthScheme, 16 | security_credentials: NoAuthSchemeCredentials, 17 | headers: dict, 18 | query: dict, 19 | body: dict, 20 | cookies: dict, 21 | ) -> None: 22 | # No authentication required, so nothing to inject 23 | pass 24 | -------------------------------------------------------------------------------- /backend/aci/server/middleware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/middleware/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/routes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/routes/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/routes/health.py: -------------------------------------------------------------------------------- 1 | from fastapi import APIRouter 2 | 3 | from aci.common.logging_setup import get_logger 4 | 5 | logger = get_logger(__name__) 6 | router = APIRouter() 7 | 8 | 9 | # TODO: add more checks? 10 | @router.get("", include_in_schema=False) 11 | async def health() -> bool: 12 | return True 13 | -------------------------------------------------------------------------------- /backend/aci/server/sentry.py: -------------------------------------------------------------------------------- 1 | import sentry_sdk 2 | 3 | from aci.server import config 4 | 5 | 6 | def setup_sentry() -> None: 7 | if config.ENVIRONMENT != "local": 8 | sentry_sdk.init( 9 | environment=config.ENVIRONMENT, 10 | dsn="https://9cebb66f55b0782e37370b08be11f1f5@o4508859021459456.ingest.us.sentry.io/4508915251871744", 11 | # Add data like request headers and IP for users, 12 | # see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info 13 | send_default_pii=True, 14 | traces_sample_rate=0.1 if config.ENVIRONMENT == "production" else 1.0, 15 | _experiments={ 16 | "continuous_profiling_auto_start": True, 17 | }, 18 | ) 19 | -------------------------------------------------------------------------------- /backend/aci/server/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/tests/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/tests/app_connectors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/tests/app_connectors/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/tests/app_connectors/integration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/tests/app_connectors/integration/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/tests/app_connectors/integration/agent_secrets_manager/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/tests/app_connectors/integration/agent_secrets_manager/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/tests/app_connectors/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/tests/app_connectors/unit/__init__.py -------------------------------------------------------------------------------- /backend/aci/server/tests/dummy_apps/aci_test/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ACI_TEST", 3 | "display_name": "ACI Test", 4 | "logo": "https://example.com/aci-logo.png", 5 | "provider": "aci", 6 | "version": "1.0.0", 7 | "description": "ACI Test is a hypothetical application used to demonstrate how API schemas can be structured. It offers basic functionalities for testing purposes such as creating resources, retrieving data, and simulating user interactions.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-Test-API-Key" 12 | }, 13 | "oauth2": { 14 | "location": "header", 15 | "name": "Authorization", 16 | "prefix": "Bearer", 17 | "client_id": "mock_client_id", 18 | "client_secret": "mock_client_secret", 19 | "scope": "openid email profile", 20 | "authorize_url": "https://api.mock.aci.com/v1/oauth2/authorize", 21 | "access_token_url": "https://api.mock.aci.com/v1/oauth2/token", 22 | "refresh_token_url": "https://api.mock.aci.com/v1/oauth2/refresh" 23 | } 24 | }, 25 | "default_security_credentials_by_scheme": { 26 | "api_key": { 27 | "secret_key": "default-shared-api-key" 28 | } 29 | }, 30 | "categories": ["testcategory", "utility"], 31 | "visibility": "public", 32 | "active": true 33 | } 34 | -------------------------------------------------------------------------------- /backend/aci/server/tests/dummy_apps/github/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GITHUB", 3 | "display_name": "GitHub", 4 | "logo": "https://example.com/logo.png", 5 | "provider": "github", 6 | "version": "1.0.0", 7 | "description": "GitHub is a cloud-based platform that enables developers to store, manage, and share their code repositories. It provides version control using Git, a system that tracks changes to files, allowing multiple people to collaborate on a project efficiently. GitHub facilitates code sharing, collaboration, and management by providing tools for version tracking, branching, and merging of code.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-API-Key" 12 | }, 13 | "oauth2": { 14 | "location": "header", 15 | "name": "Authorization", 16 | "prefix": "Bearer", 17 | "client_id": "mock_client_id", 18 | "client_secret": "mock_client_secret", 19 | "scope": "openid email profile https://www.googleapis.com/auth/calendar", 20 | "authorize_url": "https://github.com/login/oauth/authorize", 21 | "access_token_url": "https://github.com/login/oauth/access_token", 22 | "refresh_token_url": "https://github.com/login/oauth/access_token" 23 | } 24 | }, 25 | "default_security_credentials_by_scheme": {}, 26 | "categories": [ 27 | "devtools", 28 | "testcategory-2" 29 | ], 30 | "visibility": "public", 31 | "active": true 32 | } -------------------------------------------------------------------------------- /backend/aci/server/tests/dummy_apps/github/functions.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "GITHUB__CREATE_REPOSITORY", 4 | "description": "Create a new repository", 5 | "tags": ["repository"], 6 | "visibility": "public", 7 | "active": true, 8 | "protocol": "rest", 9 | "protocol_data": { 10 | "method": "POST", 11 | "path": "/repositories", 12 | "server_url": "https://api.github.com" 13 | }, 14 | "parameters": { 15 | "type": "object", 16 | "properties": { 17 | "body": { 18 | "type": "object", 19 | "properties": { 20 | "name": { 21 | "type": "string", 22 | "description": "The name of the repository" 23 | }, 24 | "description": { 25 | "type": "string", 26 | "description": "A description for the repository" 27 | }, 28 | "private": { 29 | "type": "boolean", 30 | "description": "Whether the repository is private or public" 31 | } 32 | }, 33 | "required": [ 34 | "name", 35 | "description", 36 | "private" 37 | ], 38 | "visible": ["name", "description", "private"], 39 | "additionalProperties": false 40 | } 41 | }, 42 | "required": ["body"], 43 | "visible": ["body"], 44 | "additionalProperties": false 45 | }, 46 | "response": {} 47 | } 48 | ] -------------------------------------------------------------------------------- /backend/aci/server/tests/dummy_apps/google/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GOOGLE", 3 | "display_name": "Google", 4 | "logo": "https://example.com/logo.png", 5 | "provider": "google", 6 | "version": "1.0.0", 7 | "description": "Google is a global technology company that provides a wide range of internet-based products and services. Best known for its search engine, Google enables users to search for information, websites, images, videos, and more across the web.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-API-Key" 12 | }, 13 | "oauth2": { 14 | "location": "header", 15 | "name": "Authorization", 16 | "prefix": "Bearer", 17 | "client_id": "mock_client_id", 18 | "client_secret": "mock_client_secret", 19 | "scope": "openid email profile https://www.googleapis.com/auth/calendar", 20 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 21 | "access_token_url": "https://oauth2.googleapis.com/token", 22 | "refresh_token_url": "https://oauth2.googleapis.com/token" 23 | } 24 | }, 25 | "default_security_credentials_by_scheme": {}, 26 | "categories": [ 27 | "devtools", 28 | "testcategory-2" 29 | ], 30 | "visibility": "public", 31 | "active": true 32 | } 33 | -------------------------------------------------------------------------------- /backend/aci/server/tests/dummy_apps/mock_app_connector/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MOCK_APP_CONNECTOR", 3 | "display_name": "Mock App Connector", 4 | "logo": "https://example.com/logo.png", 5 | "provider": "mock_app_connector", 6 | "version": "1.0.0", 7 | "description": "Mock App Connector", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "mock_client_id", 14 | "client_secret": "mock_client_secret", 15 | "scope": "openid email profile https://www.googleapis.com/auth/calendar", 16 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 17 | "access_token_url": "https://oauth2.googleapis.com/token", 18 | "refresh_token_url": "https://oauth2.googleapis.com/token" 19 | }, 20 | "no_auth": {} 21 | }, 22 | "default_security_credentials_by_scheme": {}, 23 | "categories": ["mock"], 24 | "visibility": "public", 25 | "active": true 26 | } 27 | -------------------------------------------------------------------------------- /backend/aci/server/tests/routes/app_configurations/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/aci/server/tests/routes/app_configurations/conftest.py -------------------------------------------------------------------------------- /backend/aci/server/tests/routes/app_configurations/test_app_configurations_get.py: -------------------------------------------------------------------------------- 1 | from fastapi import status 2 | from fastapi.testclient import TestClient 3 | 4 | from aci.common.db.sql_models import App 5 | from aci.common.schemas.app_configurations import AppConfigurationPublic 6 | from aci.server import config 7 | 8 | 9 | def test_get_app_configuration( 10 | test_client: TestClient, 11 | dummy_api_key_1: str, 12 | dummy_app_configuration_oauth2_google_project_1: AppConfigurationPublic, 13 | ) -> None: 14 | ENDPOINT = ( 15 | f"{config.ROUTER_PREFIX_APP_CONFIGURATIONS}/" 16 | f"{dummy_app_configuration_oauth2_google_project_1.app_name}" 17 | ) 18 | response = test_client.get(ENDPOINT, headers={"x-api-key": dummy_api_key_1}) 19 | 20 | assert response.status_code == status.HTTP_200_OK 21 | app_configuration = AppConfigurationPublic.model_validate(response.json()) 22 | assert app_configuration.id == dummy_app_configuration_oauth2_google_project_1.id 23 | 24 | 25 | def test_get_app_configuration_with_non_existent_app_configuration( 26 | test_client: TestClient, 27 | dummy_api_key_1: str, 28 | dummy_app_aci_test: App, 29 | ) -> None: 30 | ENDPOINT = f"{config.ROUTER_PREFIX_APP_CONFIGURATIONS}/{dummy_app_aci_test.name}" 31 | response = test_client.get(ENDPOINT, headers={"x-api-key": dummy_api_key_1}) 32 | 33 | assert response.status_code == status.HTTP_404_NOT_FOUND 34 | assert str(response.json()["error"]).startswith("App configuration not found") 35 | -------------------------------------------------------------------------------- /backend/aci/server/tests/routes/health/test_health.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from fastapi import status 4 | from fastapi.testclient import TestClient 5 | 6 | from aci.server import config 7 | 8 | logger = logging.getLogger(__name__) 9 | 10 | 11 | def test_health_check(test_client: TestClient) -> None: 12 | # Note: /v1/health will result in a redirect to /v1/health/, in which case 13 | # the return code is 30X 14 | response = test_client.get(f"{config.ROUTER_PREFIX_HEALTH}") 15 | assert response.status_code == status.HTTP_200_OK 16 | assert response.json() is True 17 | -------------------------------------------------------------------------------- /backend/aci/server/tests/security/test_api_key.py: -------------------------------------------------------------------------------- 1 | from fastapi import status 2 | from fastapi.testclient import TestClient 3 | 4 | from aci.server import config 5 | 6 | 7 | # sending a request without a valid api key in x-api-key header to /apps route should fail 8 | def test_without_api_key(test_client: TestClient) -> None: 9 | search_params: dict[str, str | list[str] | int] = { 10 | "intent": "i want to create a new code repo for my project", 11 | "categories": [], 12 | "limit": 100, 13 | "offset": 0, 14 | } 15 | response = test_client.get( 16 | f"{config.ROUTER_PREFIX_APPS}/search", 17 | params=search_params, 18 | ) 19 | assert response.status_code == status.HTTP_403_FORBIDDEN 20 | 21 | 22 | # sending a request with a invalid api key should fail 23 | def test_with_invalid_api_key(test_client: TestClient, dummy_api_key_1: str) -> None: 24 | search_params: dict[str, str | list[str] | int] = { 25 | "intent": "i want to create a new code repo for my project", 26 | "categories": [], 27 | "limit": 100, 28 | "offset": 0, 29 | } 30 | response = test_client.get( 31 | f"{config.ROUTER_PREFIX_APPS}/search", 32 | params=search_params, 33 | headers={"x-api-key": "invalid_api_key"}, 34 | ) 35 | assert response.status_code == status.HTTP_401_UNAUTHORIZED 36 | 37 | 38 | # TODO: test disabled/deleted api key 39 | -------------------------------------------------------------------------------- /backend/apps/accredible/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ACCREDIBLE", 3 | "display_name": "Accredible", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/accredible.svg", 5 | "provider": "Accredible", 6 | "version": "1.0", 7 | "description": "Accredible integration for managing digital certificates and badges. Create, search, and generate PDFs for credentials.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Token" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Document Management" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/active_campaign/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ACTIVE_CAMPAIGN", 3 | "display_name": "ActiveCampaign", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/active_campaign.svg", 5 | "provider": "ActiveCampaign, LLC", 6 | "version": "3.0.0", 7 | "description": "ActiveCampaign is a customer experience automation (CXA) platform that combines email marketing, marketing automation, sales automation and CRM capabilities to help businesses build better relationships with customers.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Api-Token", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Marketing", 18 | "CRM & Support", 19 | "Automation" 20 | ], 21 | "visibility": "public", 22 | "active": true 23 | } 24 | -------------------------------------------------------------------------------- /backend/apps/aero_workflow/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AERO_WORKFLOW", 3 | "display_name": "Aero workflow", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/aeroworkflow.svg", 5 | "provider": "Aero workflow", 6 | "version": "1.0.0", 7 | "description": "Aero is workflow & practice management built specifically with the modern cloud-based accounting firm in mind.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "apikey", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Productivity", 18 | "Automation" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/agent_mail/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AGENT_MAIL", 3 | "display_name": "Agent Mail", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/agentmail.svg", 5 | "provider": "Agent Mail", 6 | "version": "1.0.0", 7 | "description": "Agent Mail is an email service that helps manage and automate email communications with features for inbox management, thread tracking, and message handling.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Productivity", 18 | "Communication", 19 | "Email" 20 | ], 21 | "visibility": "public", 22 | "active": true 23 | } 24 | -------------------------------------------------------------------------------- /backend/apps/agent_secrets_manager/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AGENT_SECRETS_MANAGER", 3 | "display_name": "Agent Secrets Manager", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/agent_secrets_manager.svg", 5 | "provider": "ACI.dev", 6 | "version": "1.0.0", 7 | "description": "The Agent Secrets Manager allows you to store and retrieve secrets. For example, you can store username/password for a website login credential, or a secret API key for a user.", 8 | "security_schemes": { 9 | "no_auth": {} 10 | }, 11 | "default_security_credentials_by_scheme": {}, 12 | "categories": [ 13 | "Security", 14 | "Dev Tools", 15 | "ACI.dev" 16 | ], 17 | "visibility": "public", 18 | "active": true 19 | } 20 | -------------------------------------------------------------------------------- /backend/apps/aidbase/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AIDBASE", 3 | "display_name": "AIDBASE", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/aidbase.svg", 5 | "provider": "Aidbase, Inc.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "Integration with Aidbase API to manage resources and workflows.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Integration", 18 | "Automation" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/airtable/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AIRTABLE", 3 | "display_name": "Airtable", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/airtable.svg", 5 | "provider": "Airtable", 6 | "version": "1.0.0", 7 | "description": "Airtable is a cloud-based platform that combines the functionality of a database with the visual interface of a spreadsheet. It allows users to organize and track information, collaborate with team members, and create custom applications.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Data & Analytics", 18 | "Productivity" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/akkio/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AKKIO", 3 | "display_name": "Akkio", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/akkio.svg", 5 | "provider": "Akkio", 6 | "version": "1.0.0", 7 | "description": "Akkio is a no-code AI platform that enables businesses to build, deploy, and maintain AI solutions for predictive analytics, forecasting, and classification without requiring data science expertise.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "api_key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Data & Analytics", 18 | "Automation" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/all_images/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ALL_IMAGES", 3 | "display_name": "All-Images", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/all_images.svg", 5 | "provider": "All-Images.ai", 6 | "version": "1.0", 7 | "description": "All-Images.ai API integration for image search and AI image generation. Provides capabilities for searching stock images and generating custom images using AI.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "api-key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Media" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/anchor_browser/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ANCHOR_BROWSER", 3 | "display_name": "Anchor Browser", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/anchor_browser.svg", 5 | "provider": "Anchor Browser Inc.", 6 | "version": "1.0.0", 7 | "description": "Anchor Browser is a powerful web browser application that provides secure browsing, tabbed navigation, and built-in privacy features. It enables users to browse websites, manage bookmarks, and synchronize browsing data across multiple devices while maintaining privacy and security.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "anchor-api-key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Browser", 18 | "Productivity" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/apaleo/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "APALEO", 3 | "display_name": "APALEO", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/apaleo.svg", 5 | "provider": "Apaleo", 6 | "version": "1.0", 7 | "description": "The open platform for modern hospitality. Hotel and apartment businesses run more efficiently on Apaleo today and use innovative apps to be ready for tomorrow.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Hospitality" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/api_template/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "API_TEMPLATE", 3 | "display_name": "APITemplate.io", 4 | "description": "APITemplate.io is a template-based document generation service that allows you to create PDFs and other documents from HTML templates.", 5 | "provider": "APITemplate.io", 6 | "version": "1.0.0", 7 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/apitemplate.svg", 8 | "categories": [ 9 | "Document Management" 10 | ], 11 | "security_schemes": { 12 | "api_key": { 13 | "location": "header", 14 | "name": "X-API-KEY", 15 | "prefix": null 16 | } 17 | }, 18 | "default_security_credentials_by_scheme": {}, 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/arxiv/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ARXIV", 3 | "display_name": "arXiv", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/arxiv.svg", 5 | "provider": "Cornell University", 6 | "version": "1.0.0", 7 | "description": "arXiv is an open-access repository of electronic preprints and postprints approved for posting after moderation, but not peer review. It consists of scientific papers in the fields of mathematics, physics, astronomy, electrical engineering, computer science, quantitative biology, statistics, mathematical finance and economics.", 8 | "security_schemes": { 9 | "no_auth": {} 10 | }, 11 | "default_security_credentials_by_scheme": {}, 12 | "categories": [ 13 | "Research" 14 | ], 15 | "visibility": "public", 16 | "active": true 17 | } 18 | -------------------------------------------------------------------------------- /backend/apps/asana/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ASANA", 3 | "display_name": "ASANA", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/asana.png", 5 | "provider": "ASANA, Inc.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "Integration with ASANA Support API to manage users, tickets, and organizations.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Productivity", 18 | "CRM & Support" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/baidu_map/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BAIDU_MAP", 3 | "display_name": "Baidu Map", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/baidu_map.svg", 5 | "provider": "Baidu", 6 | "version": "1.0.0", 7 | "description": "Baidu Map API is a set of map-based application interfaces for developers, providing services such as location search, geocoding, route planning, and real-time traffic conditions.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "ak", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Location" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/baserow/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BASEROW", 3 | "display_name": "Baserow", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/baserow.svg", 5 | "provider": "Baserow", 6 | "version": "2024-03-21", 7 | "description": "Baserow is an open source no-code database tool and Airtable alternative. Create your own database without technical experience.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Token" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Data & Analytics", 18 | "Productivity" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/brave_search/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BRAVE_SEARCH", 3 | "display_name": "Brave Search", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/brave_search.svg", 5 | "provider": "Brave Software, Inc.", 6 | "version": "1.0.0", 7 | "description": "Brave Search API is a REST API to query Brave Search and get back search results from the web. It supports web search, summarizer search, image search, video search, news search.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-Subscription-Token", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/breezy/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BREEZY", 3 | "display_name": "Breezy HR", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/breezy.svg", 5 | "provider": "Breezy HR", 6 | "version": "aipolabs_0.0.1", 7 | "description": "Breezy HR is an applicant tracking system that helps companies streamline their hiring process with features for job posting, candidate management, and interview scheduling.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "HR" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/browserbase/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BROWSERBASE", 3 | "display_name": "Browserbase", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/browserbase.png", 5 | "provider": "Browserbase", 6 | "version": "1.0.0", 7 | "description": "Browserbase is a platform for running headless browsers.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "x-bb-api-key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Browser", 18 | "Search & Scraping" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/cal/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CAL", 3 | "display_name": "Cal.com", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/cal.svg", 5 | "provider": "Cal.com, Inc.", 6 | "version": "1.0.0", 7 | "description": "Cal.com is a fully customizable scheduling platform that enables individuals and teams to automate meeting bookings, manage availability, and integrate with popular calendar and productivity tools. With Cal.com, users can streamline appointment scheduling, avoid double bookings, and enhance collaboration through flexible, privacy-focused solutions.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "apiKey", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Productivity", 18 | "Communication" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/calendly/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CALENDLY", 3 | "display_name": "Calendly", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/calendly.svg", 5 | "provider": "Calendly", 6 | "version": "1.0", 7 | "description": "Calendly integration for scheduling and managing meetings. This app allows you to automate your scheduling process, embed Calendly on your website, and manage your availability.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_CALENDLY_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_CALENDLY_CLIENT_SECRET }}", 15 | "scope": "default", 16 | "authorize_url": "https://auth.calendly.com/oauth/authorize", 17 | "access_token_url": "https://auth.calendly.com/oauth/token", 18 | "refresh_token_url": "https://auth.calendly.com/oauth/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Productivity" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/apps/clickup/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CLICKUP", 3 | "display_name": "ClickUp", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/clickup.png", 5 | "provider": "ClickUp", 6 | "version": "4.0.0", 7 | "description": "The ClickUp API allows you to interact with ClickUp programmatically, including workspace management, tasks, lists, folders, and more.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_CLICKUP_APP_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_CLICKUP_APP_CLIENT_SECRET }}", 15 | "scope": "", 16 | "authorize_url": "https://app.clickup.com/api", 17 | "access_token_url": "https://api.clickup.com/api/v2/oauth/token", 18 | "refresh_token_url": "https://api.clickup.com/api/v2/oauth/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Productivity" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/apps/cloudflare/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CLOUDFLARE", 3 | "display_name": "Cloudflare", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/cloudflare.png", 5 | "provider": "https://developers.cloudflare.com/api", 6 | "version": "1.0.0", 7 | "description": "The Cloudflare API allows programmatic control over your Cloudflare account, including DNS, DDoS protection, and more.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": ["Deployment"], 17 | "visibility": "public", 18 | "active": true 19 | } 20 | -------------------------------------------------------------------------------- /backend/apps/coda/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CODA", 3 | "display_name": "Coda", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/coda.svg", 5 | "provider": "Coda, Inc.", 6 | "version": "1.0.0", 7 | "description": "Coda is a document editor that brings together documents, spreadsheets, and applications into a single flexible platform. It allows teams to collaborate in real-time, create interactive documents, and build custom workflows without coding.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Document Management", 18 | "Productivity" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/cognito_forms/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "COGNITO_FORMS", 3 | "display_name": "Cognito Forms", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/cognito_forms.svg", 5 | "provider": "Cognito LLC", 6 | "version": "1.0.0", 7 | "description": "Cognito Forms is a powerful online form builder that allows users to create custom forms, collect data, and automatically process payments. The tool supports complex field types, conditional logic, calculated fields, file uploads, and multiple integration options.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Productivity", 18 | "Data & Analytics" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/coin_gecko/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "COIN_GECKO", 3 | "display_name": "CoinGecko", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/coingecko.svg", 5 | "provider": "CoinGecko", 6 | "version": "1.0.0", 7 | "description": "CoinGecko provides a comprehensive cryptocurrency API that allows users to track price, volume, market cap, and other market data for thousands of cryptocurrencies. It offers real-time market data, historical price information, and various market metrics for digital assets.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "x_cg_pro_api_key" 12 | } 13 | }, 14 | "default_security_credentials_by_scheme": {}, 15 | "categories": [ 16 | "Finance", 17 | "Blockchain" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/coinmarketcap/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "COINMARKETCAP", 3 | "display_name": "CoinMarketCap", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/coinmarketcap.svg", 5 | "provider": "CoinMarketCap, Inc.", 6 | "version": "1.0.0", 7 | "description": "CoinMarketCap API provides cryptocurrency market data including listings, quotes, mapping and global metrics. API accessible is subject to the pricing tier of the user.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-CMC_PRO_API_KEY", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Finance", 18 | "Blockchain" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/daytona/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DAYTONA", 3 | "display_name": "Daytona.io", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/daytona.svg", 5 | "provider": "Daytona.io", 6 | "version": "1.0.0", 7 | "description": "Daytona provides secure and elastic infrastructure for running AI-generated code in isolated environments with sub-90ms sandbox creation time.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Sandboxes", 18 | "Code" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/dexscreener/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DEXSCREENER", 3 | "display_name": "DexScreener", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/dexscreener.svg", 5 | "provider": "DexScreener", 6 | "version": "1.0.0", 7 | "description": "DexScreener API integration for accessing token and pair information from decentralized exchanges.", 8 | "security_schemes": { 9 | "no_auth": {} 10 | }, 11 | "default_security_credentials_by_scheme": {}, 12 | "categories": [ 13 | "Finance", 14 | "Blockchain" 15 | ], 16 | "visibility": "public", 17 | "active": true 18 | } 19 | -------------------------------------------------------------------------------- /backend/apps/dify/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DIFY", 3 | "display_name": "Dify", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/dify.svg", 5 | "provider": "Dify", 6 | "version": "1.0.0", 7 | "description": "Dify API for managing AI-driven tasks and workflows.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Automation" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/discord/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DISCORD", 3 | "display_name": "Discord", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/discord.svg", 5 | "provider": "Discord Inc.", 6 | "version": "10.0.0", 7 | "description": "Discord is a voice, video, and text communication service. This API allows you to interact with Discord in two ways: as a bot for automated tasks and workflows, or as a user to perform actions on behalf of a real Discord user. Whether you're building chatbots, automating workflows, or integrating Discord with other tools, this API provides the flexibility to suit your needs.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_DISCORD_APP_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_DISCORD_APP_CLIENT_SECRET }}", 15 | "scope": "identify email openid connections guilds guilds.join guilds.members.read applications.commands messages.read", 16 | "token_endpoint_auth_method": "client_secret_post", 17 | "authorize_url": "https://discord.com/api/oauth2/authorize", 18 | "access_token_url": "https://discord.com/api/oauth2/token", 19 | "refresh_token_url": "https://discord.com/api/oauth2/token" 20 | } 21 | }, 22 | "default_security_credentials_by_scheme": {}, 23 | "categories": [ 24 | "Communication" 25 | ], 26 | "visibility": "public", 27 | "active": true 28 | } 29 | -------------------------------------------------------------------------------- /backend/apps/discord/functions.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "DISCORD__GET_CURRENT_USER", 4 | "description": "Get a user object for the current user.", 5 | "tags": ["user", "info"], 6 | "visibility": "public", 7 | "active": true, 8 | "protocol": "rest", 9 | "protocol_data": { 10 | "method": "GET", 11 | "path": "/users/@me", 12 | "server_url": "https://discord.com/api/v10" 13 | }, 14 | "parameters": { 15 | "type": "object", 16 | "properties": {}, 17 | "required": [], 18 | "visible": [], 19 | "additionalProperties": false 20 | } 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /backend/apps/e2b/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "E2B", 3 | "display_name": "E2B", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/e2b.svg", 5 | "provider": "FoundryLabs, Inc.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "E2B is an open-source runtime for executing AI-generated code in secure cloud sandboxes.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "E2B_API_KEY", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Sandboxes", 18 | "Code" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/e2b/functions.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "E2B__RUN_CODE", 4 | "description": "Runs code in an E2B.dev sandbox", 5 | "tags": ["sandbox", "run", "code"], 6 | "visibility": "public", 7 | "active": true, 8 | "protocol": "connector", 9 | "protocol_data": {}, 10 | "parameters": { 11 | "type": "object", 12 | "properties": { 13 | "code": { 14 | "type": "string", 15 | "description": "The python code to run in the sandbox" 16 | } 17 | }, 18 | "required": ["code"], 19 | "visible": ["code"], 20 | "additionalProperties": false 21 | } 22 | } 23 | ] -------------------------------------------------------------------------------- /backend/apps/eleven_labs/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ELEVEN_LABS", 3 | "display_name": "Eleven Labs", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/eleven_labs.svg", 5 | "provider": "Eleven Labs", 6 | "version": "1.0.0", 7 | "description": "Eleven Labs is an advanced text-to-speech (TTS) platform that provides high-quality, natural Text To Speech services. It allows users to create custom voices, convert text into realistic speech, and supports multiple languages and sound styles.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "xi-api-key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Media" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/etherscan/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ETHERSCAN", 3 | "display_name": "Etherscan", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/etherscan.svg", 5 | "provider": "Etherscan", 6 | "version": "1.0", 7 | "description": "The Etherscan API provides access to Ethereum blockchain data, including account balances, transactions, smart contracts, and network statistics.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "apikey", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Blockchain", 18 | "Data & Analytics" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/exa_ai/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "EXA_AI", 3 | "display_name": "Exa AI", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/exa_ai.svg", 5 | "provider": "Exa Labs, Inc.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "Exa is a search engine made for AIs. Exa finds the exact content you are looking for on the web, with three core functionalities: search, contents, find similar.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-API-KEY", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/factorialhr/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FACTORIAL_HR", 3 | "display_name": "Factorial HR", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/factorialhr.svg", 5 | "provider": "Factorial", 6 | "version": "2025-04-01", 7 | "description": "Factorial HR API provides comprehensive HR management capabilities including employee management, task tracking, webhooks, job catalog, and finance management.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "x-api-key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "HR & Workforce" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/feishu/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FEISHU", 3 | "display_name": "Feishu", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/feishu.svg", 5 | "provider": "ByteDance", 6 | "version": "1.0.0", 7 | "description": "Feishu (Lark) is a suite of workplace collaboration tools developed by ByteDance. It provides APIs for messaging, document collaboration, and workplace automation.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Communication", 18 | "Productivity" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/figma/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FIGMA", 3 | "display_name": "Figma", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/figma.svg", 5 | "provider": "Figma", 6 | "version": "1.0.0", 7 | "description": "Figma is a browser-based collaborative interface design tool. This integration allows access to and processing of Figma design files and resources.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-Figma-Token", 12 | "prefix": null 13 | }, 14 | "oauth2": { 15 | "location": "header", 16 | "name": "Authorization", 17 | "prefix": "Bearer", 18 | "client_id": "{{ AIPOLABS_FIGMA_APP_CLIENT_ID }}", 19 | "client_secret": "{{ AIPOLABS_FIGMA_APP_CLIENT_SECRET }}", 20 | "scope": "current_user:read file_comments:read file_comments:write file_content:read file_dev_resources:read file_dev_resources:write file_metadata:read file_variables:read file_variables:write file_versions:read files:read library_analytics:read library_assets:read library_content:read projects:read team_library_content:read webhooks:read webhooks:write", 21 | "authorize_url": "https://www.figma.com/oauth", 22 | "access_token_url": "https://api.figma.com/v1/oauth/token", 23 | "refresh_token_url": "https://api.figma.com/v1/oauth/refresh" 24 | } 25 | }, 26 | "default_security_credentials_by_scheme": {}, 27 | "categories": [ 28 | "Media & Design" 29 | ], 30 | "visibility": "public", 31 | "active": true 32 | } 33 | -------------------------------------------------------------------------------- /backend/apps/firecrawl/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FIRECRAWL", 3 | "display_name": "Firecrawl", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/firecrawl.svg", 5 | "provider": "Firecrawl", 6 | "version": "1.0.0", 7 | "description": "Firecrawl API provides web scraping, crawling, mapping, extraction, and search capabilities. Extract content from any webpage, crawl entire websites, get complete URL lists, extract structured data, and search the web.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping", 18 | "Data & Analytics" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/fireflies/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FIREFLIES", 3 | "display_name": "Fireflies", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/fireflies.svg", 5 | "provider": "Fireflies.ai", 6 | "version": "1.0.0", 7 | "description": "Fireflies.ai is an AI meeting assistant that automatically records, transcribes, and analyzes your meetings. It helps teams capture and retrieve knowledge from voice conversations across all video conferencing platforms.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Productivity", 18 | "Communication" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/github/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GITHUB", 3 | "display_name": "GitHub", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/github.svg", 5 | "provider": "GitHub", 6 | "version": "2022-11-28", 7 | "description": "The GitHub API allows you to interact with GitHub programmatically, including repository management, pull requests, issues, commits, and more.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_GITHUB_APP_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_GITHUB_APP_CLIENT_SECRET }}", 15 | "scope": "public_repo gist user workflow", 16 | "authorize_url": "https://github.com/login/oauth/authorize", 17 | "access_token_url": "https://github.com/login/oauth/access_token", 18 | "refresh_token_url": "https://github.com/login/oauth/access_token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Dev Tools" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/apps/gmail/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GMAIL", 3 | "display_name": "Gmail", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/gmail.svg", 5 | "provider": "Google", 6 | "version": "1.0.0", 7 | "description": "The Gmail API is a RESTful API that enables sending, reading, and managing emails. This integration allows sending emails on behalf of the user.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_GMAIL_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_GMAIL_CLIENT_SECRET }}", 15 | "scope": "https://www.googleapis.com/auth/gmail.labels https://www.googleapis.com/auth/gmail.send https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/gmail.compose https://www.googleapis.com/auth/gmail.insert https://www.googleapis.com/auth/gmail.modify https://mail.google.com/", 16 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 17 | "access_token_url": "https://oauth2.googleapis.com/token", 18 | "refresh_token_url": "https://oauth2.googleapis.com/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Communication" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/apps/goco/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GOCO", 3 | "display_name": "GoCo", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/goco.svg", 5 | "provider": "GoCo", 6 | "version": "1.0.0", 7 | "description": "GoCo API for managing HR, benefits, and payroll operations.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "HR & Workforce", 18 | "Finance" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/google_analytics_admin/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GOOGLE_ANALYTICS_ADMIN", 3 | "display_name": "Google Analytics Admin", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/google_analytics.svg", 5 | "provider": "Google", 6 | "version": "1.0.0", 7 | "description": "The Google Analytics Admin API allows for programmatic access to the Google Analytics configuration data and is only compatible with Google Analytics properties.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_GOOGLE_ANALYTICS_ADMIN_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_GOOGLE_ANALYTICS_ADMIN_CLIENT_SECRET }}", 15 | "scope": "https://www.googleapis.com/auth/analytics.readonly https://www.googleapis.com/auth/analytics.edit", 16 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 17 | "access_token_url": "https://oauth2.googleapis.com/token", 18 | "refresh_token_url": "https://oauth2.googleapis.com/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Data & Analytics", 24 | "Marketing" 25 | ], 26 | "visibility": "public", 27 | "active": true 28 | } 29 | -------------------------------------------------------------------------------- /backend/apps/google_calendar/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GOOGLE_CALENDAR", 3 | "display_name": "Google Calendar", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/google_calendar.svg", 5 | "provider": "Google", 6 | "version": "3.0.0", 7 | "description": "The Google Calendar API is a RESTful API that can be accessed through explicit HTTP calls. The API exposes most of the features available in the Google Calendar Web interface.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_GOOGLE_CALENDAR_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_GOOGLE_CALENDAR_CLIENT_SECRET }}", 15 | "scope": "https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events", 16 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 17 | "access_token_url": "https://oauth2.googleapis.com/token", 18 | "refresh_token_url": "https://oauth2.googleapis.com/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Productivity" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/apps/google_docs/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GOOGLE_DOCS", 3 | "display_name": "Google Docs", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/google_docs.svg", 5 | "provider": "Google", 6 | "version": "1.0.0", 7 | "description": "The Google Docs API allows developers to create, read, and update Google Docs documents programmatically. It provides access to Google Docs through RESTful HTTP calls, including create, read and update the Google Docs document.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_GOOGLE_DOCS_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_GOOGLE_DOCS_CLIENT_SECRET }}", 15 | "scope": "https://www.googleapis.com/auth/documents", 16 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 17 | "access_token_url": "https://oauth2.googleapis.com/token", 18 | "refresh_token_url": "https://oauth2.googleapis.com/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Document Management" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/apps/google_maps/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GOOGLE_MAPS", 3 | "display_name": "Google MAPS", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/google_maps.svg", 5 | "provider": "Google", 6 | "version": "2025-04-09", 7 | "description": "Navigate your world faster and easier with Google Maps. Over 220 countries and territories mapped and hundreds of millions of businesses and places on the map. Get real-time GPS navigation, traffic, and transit info, and find what you need by getting the latest information on businesses, including grocery stores, pharmacies and other important places.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Map" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/google_sheets/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GOOGLE_SHEETS", 3 | "display_name": "Google Sheets", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/google_sheets.svg", 5 | "provider": "Google", 6 | "version": "4.0.0", 7 | "description": "The Google Sheets API is a RESTful API that allows programmatic access to spreadsheet data and formatting. It supports CRUD operations, formulas, charts, and collaboration features.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_GOOGLE_SHEETS_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_GOOGLE_SHEETS_CLIENT_SECRET }}", 15 | "scope": "https://www.googleapis.com/auth/spreadsheets", 16 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 17 | "access_token_url": "https://oauth2.googleapis.com/token", 18 | "refresh_token_url": "https://oauth2.googleapis.com/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Data & Analytics", 24 | "Productivity" 25 | ], 26 | "visibility": "public", 27 | "active": true 28 | } 29 | -------------------------------------------------------------------------------- /backend/apps/google_tasks/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GOOGLE_TASKS", 3 | "display_name": "Google Tasks", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/google_tasks.svg", 5 | "provider": "Google", 6 | "version": "2.0.0", 7 | "description": "The Google Tasks API allows managing tasks and task lists programmatically.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_GOOGLE_TASKS_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_GOOGLE_TASKS_CLIENT_SECRET }}", 15 | "scope": "https://www.googleapis.com/auth/tasks", 16 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 17 | "access_token_url": "https://oauth2.googleapis.com/token", 18 | "refresh_token_url": "https://oauth2.googleapis.com/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Productivity" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/apps/hackernews/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HACKERNEWS", 3 | "display_name": "Hacker News", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/hackernews.png", 5 | "provider": "Hacker News", 6 | "version": "1.0.0", 7 | "description": "Hacker News is a social news website focusing on computer science and entrepreneurship, run by Y Combinator. This API allows you to fetch top stories, new stories, ask stories, show stories, and job postings from Hacker News.", 8 | "security_schemes": { 9 | "no_auth": {} 10 | }, 11 | "default_security_credentials_by_scheme": {}, 12 | "categories": [ 13 | "News" 14 | ], 15 | "visibility": "public", 16 | "active": true 17 | } 18 | -------------------------------------------------------------------------------- /backend/apps/holded/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HOLDED", 3 | "display_name": "Holded", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/holded.svg", 5 | "provider": "Holded", 6 | "version": "1.0.0", 7 | "description": "Holded API for managing team, employees, payroll, treasury, invoicing and other business operations.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Finance", 18 | "HR & Workforce" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/lmnt/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LMNT", 3 | "display_name": "LMNT", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/lmnt.jpg", 5 | "provider": "LMNT Inc.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "LMNT is an API for text-to-speech and voice cloning.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-API-Key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Media" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/neon/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NEON", 3 | "display_name": "Neon", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/neon.png", 5 | "provider": "Neon Tech, Inc.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "Neon is a serverless Postgres database service with a generous free tier, providing instant autoscaling and automated storage optimization.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Data & Analytics", 18 | "Dev Tools" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/notion/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NOTION", 3 | "display_name": "Notion", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/notion.svg", 5 | "provider": "Notion Labs, Inc.", 6 | "version": "2022-06-28", 7 | "description": "Notion API is a REST API to manage Notion workspaces which are collaborative environments where teams can organize work, manage projects, and store information in a highly customizable way.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_NOTION_APP_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_NOTION_APP_CLIENT_SECRET }}", 15 | "scope": "", 16 | "authorize_url": "https://api.notion.com/v1/oauth/authorize", 17 | "access_token_url": "https://api.notion.com/v1/oauth/token", 18 | "refresh_token_url": "https://api.notion.com/v1/oauth/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Productivity", 24 | "Document Management" 25 | ], 26 | "visibility": "public", 27 | "active": true 28 | } 29 | -------------------------------------------------------------------------------- /backend/apps/notte/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NOTTE", 3 | "display_name": "Notte.cc", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/notte.png", 5 | "provider": "Notte Labs", 6 | "version": "1.0.0", 7 | "description": "Notte transforms the internet into a space where each website becomes a structured, navigable map for intelligent agents.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/one_page_crm/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ONE_PAGE_CRM", 3 | "display_name": "OnePageCRM", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/one_page_crm.svg", 5 | "provider": "OnePageCRM", 6 | "version": "1.0.0", 7 | "description": "OnePageCRM API for managing contacts, sales actions, and customer relationship management.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Basic" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "CRM & Support" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/one_signal/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ONE_SIGNAL", 3 | "display_name": "OneSignal", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/one_signal.svg", 5 | "provider": "OneSignal Inc.", 6 | "version": "1.0.0", 7 | "description": "OneSignal is a comprehensive customer engagement solution that provides push notifications, in-app messaging, email, and SMS services. This integration enables managing and sending cross-platform notifications, tracking user engagement, and accessing notification analytics.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Key" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Communication", 18 | "Marketing" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/open_weather_map/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OPEN_WEATHER_MAP", 3 | "display_name": "Open Weather Map", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/open_weather_map.svg", 5 | "provider": "OpenWeather Ltd.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "OpenWeatherMap provides comprehensive weather data including current conditions and 5-day/3-hour forecasts. The API delivers accurate weather information based on the proprietary OpenWeather Model. This integration uses the free API endpoints (Current Weather Data and 5-day/3-hour Forecast) which are available on the free plan with a limit of 1,000 calls per day.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "appid", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Weather" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/paddle/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PADDLE", 3 | "display_name": "Paddle", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/paddle.jpeg", 5 | "provider": "Paddle", 6 | "version": "1.0.0", 7 | "description": "Paddle is a complete payments infrastructure for SaaS companies. It helps businesses sell software globally with checkout, subscriptions, taxes, anti-fraud, and financial services all in one unified platform.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Finance" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/posthog/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "POSTHOG", 3 | "display_name": "PostHog", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/posthog.svg", 5 | "provider": "PostHog", 6 | "version": "2025-03-07", 7 | "description": "The PostHog API", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Data & Analytics", 18 | "Marketing" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/reddit/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "REDDIT", 3 | "display_name": "Reddit", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/reddit.svg", 5 | "provider": "Reddit", 6 | "version": "1.0", 7 | "description": "The Reddit API allows you to interact with Reddit programmatically, including post management, comments, user interactions, and subreddit operations.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_REDDIT_APP_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_REDDIT_APP_CLIENT_SECRET }}", 15 | "token_endpoint_auth_method": "client_secret_basic", 16 | "scope": "identity read vote submit flair edit history mysubreddits", 17 | "authorize_url": "https://www.reddit.com/api/v1/authorize", 18 | "access_token_url": "https://www.reddit.com/api/v1/access_token", 19 | "refresh_token_url": "https://www.reddit.com/api/v1/access_token" 20 | } 21 | }, 22 | "default_security_credentials_by_scheme": {}, 23 | "categories": [ 24 | "Communication" 25 | ], 26 | "visibility": "public", 27 | "active": true 28 | } 29 | -------------------------------------------------------------------------------- /backend/apps/resend/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RESEND", 3 | "display_name": "Resend", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/resend.svg", 5 | "provider": "Resend", 6 | "version": "1.0.0", 7 | "description": "Resend is the email API for developers. It provides a modern API for sending transactional emails, managing email templates, and tracking email delivery status with comprehensive analytics.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Communication" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/rocketlane/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ROCKETLANE", 3 | "display_name": "Rocketlane", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/rocketlane.svg", 5 | "provider": "Rocketlane", 6 | "version": "1.0.0", 7 | "description": "Rocketlane API for managing customer onboarding, project management, and client collaboration.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "api-key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Productivity", 18 | "CRM & Support" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/rossum/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ROSSUM", 3 | "display_name": "Rossum", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/rossum.svg", 5 | "provider": "Resend", 6 | "version": "1.0.0", 7 | "description": "Automate complex transactional workflows with Rossum's AI document processing solution. Reduce manual tasks, increase accuracy, drive efficiency.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Document Management", 18 | "Automation" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/scrapybara/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SCRAPYBARA", 3 | "display_name": "Scrapybara", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/scrapybara.webp", 5 | "provider": "Scrapybara", 6 | "version": "1.0.0", 7 | "description": "Scrapybara is a web scraping API designed for developers. It provides a powerful, fast, and simple interface to scrape any webpage and extract structured content in real time.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "x-api-key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/sendgrid/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SENDGRID", 3 | "display_name": "SendGrid", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/sendgrid.svg", 5 | "provider": "SendGrid", 6 | "version": "3.0.0", 7 | "description": "SendGrid is a cloud-based email service that delivers transactional and marketing emails. It provides a robust API for sending emails, managing email templates, and tracking email delivery status.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Communication" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/sentry/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SENTRY", 3 | "display_name": "Sentry", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/sentry.svg", 5 | "provider": "Sentry", 6 | "version": "1.0", 7 | "description": "Sentry API integration for monitoring and error tracking, allowing you to manage issues, events, releases, and more.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Dev Tools" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/serpapi/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SERPAPI", 3 | "display_name": "SerpApi", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/serpapi.svg", 5 | "provider": "SerpApi", 6 | "version": "1.0", 7 | "description": "SerpApi integration for web search, images, news, academic papers, and trends, providing access to Google Search, Images, News, Scholar, and Trends APIs.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "api_key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/share_point/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SHARE_POINT", 3 | "display_name": "SharePoint", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/sharepoint.png", 5 | "provider": "Microsoft", 6 | "version": "2.0.0", 7 | "description": "The Microsoft Graph SharePoint API enables access to SharePoint sites, lists, libraries, and files. This integration allows reading and managing SharePoint content on behalf of the user.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_SHARE_POINT_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_SHARE_POINT_CLIENT_SECRET }}", 15 | "scope": "Sites.Manage.All Sites.Read.All Sites.ReadWrite.All Sites.Selected Files.ReadWrite.All User.Read offline_access", 16 | "authorize_url": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", 17 | "access_token_url": "https://login.microsoftonline.com/common/oauth2/v2.0/token", 18 | "refresh_token_url": "https://login.microsoftonline.com/common/oauth2/v2.0/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Productivity", 24 | "Document Management" 25 | ], 26 | "visibility": "public", 27 | "active": true 28 | } 29 | -------------------------------------------------------------------------------- /backend/apps/slack/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SLACK", 3 | "display_name": "Slack", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/slack.svg", 5 | "provider": "Slack Technologies, LLC, a Salesforce company.", 6 | "version": "2.33.0", 7 | "description": "Slack is a team communication and collaboration tool. This API allows you to interact with Slack in two ways: as a bot for automated tasks and workflows, or as a user to perform actions on behalf of a real Slack user. Whether you're building chatbots, automating workflows, or integrating Slack with other tools, this API provides the flexibility to suit your needs.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_SLACK_APP_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_SLACK_APP_CLIENT_SECRET }}", 15 | "scope": "users:read users:write channels:read groups:read groups:write im:read im:write mpim:read chat:write channels:history groups:history mpim:history im:history bookmarks:write bookmarks:read pins:write pins:read reactions:read reactions:write reminders:write reminders:read emoji:read search:read team:read", 16 | "token_endpoint_auth_method": "client_secret_post", 17 | "authorize_url": "https://slack.com/oauth/v2/authorize", 18 | "access_token_url": "https://slack.com/api/oauth.v2.access", 19 | "refresh_token_url": "https://slack.com/api/oauth.v2.access" 20 | } 21 | }, 22 | "default_security_credentials_by_scheme": {}, 23 | "categories": [ 24 | "Communication" 25 | ], 26 | "visibility": "public", 27 | "active": true 28 | } 29 | -------------------------------------------------------------------------------- /backend/apps/solscan/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SOLSCAN", 3 | "display_name": "SolScan", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/solscan.svg", 5 | "provider": "SolScan", 6 | "version": "1.0.0", 7 | "description": "SolScan integration for Solana blockchain data, providing access to transactions, accounts, and smart contracts.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "token", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Blockchain", 18 | "Data & Analytics" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/steel/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "STEEL", 3 | "display_name": "Steel.dev", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/steel.png", 5 | "provider": "Steel.dev", 6 | "version": "1.0.0", 7 | "description": "API for browser automation, web scraping, screenshot capture, and PDF generation with session management capabilities.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "steel-api-key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping", 18 | "Browser" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/supabase/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SUPABASE", 3 | "display_name": "Supabase API", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/supabase.svg", 5 | "provider": "Supabase Inc.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "Supabase is an open-source Firebase alternative providing real-time databases, authentication, and more.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer " 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Data & Analytics", 18 | "Dev Tools" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/tavily/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TAVILY", 3 | "display_name": "Tavily", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/tavily.svg", 5 | "provider": "Tavily, Inc.", 6 | "version": "aipolabs_0.0.1", 7 | "description": "Tavily is a search tool that focuses on optimizing search for AI developers and autonomous AI agents. We take care of all the burden of searching, scraping, filtering and extracting.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "body", 11 | "name": "api_key", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/tines/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TINES", 3 | "display_name": "Tines", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/tines.svg", 5 | "provider": "Tines", 6 | "version": "1.0.0", 7 | "description": "Tines is a no-code automation platform that allows security and operations teams to automate any manual workflow with a drag-and-drop interface. It provides powerful API capabilities for team management and workflow automation.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Automation", 18 | "Integration" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/typefully/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TYPEFULLY", 3 | "display_name": "Typefully", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/typefully.svg", 5 | "provider": "Typefully", 6 | "version": "1.0.0", 7 | "description": "Typefully is a Twitter/X writing platform that helps users create, schedule, and publish better tweets and threads. It provides powerful API capabilities for draft management and content scheduling.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "X-API-KEY", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Marketing", 18 | "Productivity" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/ultra_msg/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ULTRA_MSG", 3 | "display_name": "Ultra Msg", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/ultra_msg.svg", 5 | "provider": "Ultra Msg", 6 | "version": "1.0.0", 7 | "description": "Ultra Msg is a WhatsApp API service that allows users to send and receive WhatsApp messages, manage contacts and groups, and automate WhatsApp workflows. This integration allows you to programmatically send text, pictures, documents and other media types of messages through WhatsApp.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "body", 11 | "name": "token", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Communication" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/vercel/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "VERCEL", 3 | "display_name": "Vercel", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/vercel.png", 5 | "provider": "https://vercel.com/docs/rest-api/reference", 6 | "version": "1.0.0", 7 | "description": "The Vercel API allows programmatic control over deployments, projects, and integrations, including GitHub repository linking and deployment management.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Deployment", 18 | "CI/CD" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/wrike/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WRIKE", 3 | "display_name": "Wrike", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/wrike.svg", 5 | "provider": "Wrike, Inc.", 6 | "version": "1.0.0", 7 | "description": "Wrike is an intelligent work management platform that provides project management, task tracking, collaboration and workflow automation capabilities. It enables teams to centrally manage projects, automate repetitive tasks, customize workspaces, and gain key insights through real-time reports and dashboards.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "bearer" 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Productivity", 18 | "Automation" 19 | ], 20 | "visibility": "public", 21 | "active": true 22 | } 23 | -------------------------------------------------------------------------------- /backend/apps/youtube/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "YOUTUBE", 3 | "display_name": "YouTube", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/youtube.svg", 5 | "provider": "Google LLC", 6 | "version": "1.0.0", 7 | "description": "YouTube API provides access to Google's streaming video repository, allowing you to search for videos, retrieve standard feeds, and manage YouTube subscriptions and playlists.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Bearer", 13 | "client_id": "{{ AIPOLABS_YOUTUBE_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_YOUTUBE_CLIENT_SECRET }}", 15 | "scope": "https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.channel-memberships.creator https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/youtube.readonly https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtubepartner https://www.googleapis.com/auth/youtubepartner-channel-audit", 16 | "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth", 17 | "access_token_url": "https://oauth2.googleapis.com/token", 18 | "refresh_token_url": "https://oauth2.googleapis.com/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "Media" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/apps/zenrows/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ZENROWS", 3 | "display_name": "ZenRows", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/zenrows.svg", 5 | "provider": "ZenRows", 6 | "version": "1.0.0", 7 | "description": "ZenRows is a powerful web scraping API that simplifies data extraction from any website. It handles rotating proxies, headless browsers, CAPTCHAs, and advanced anti-bot systems, providing a seamless solution for developers and businesses to collect web data efficiently.", 8 | "security_schemes": { 9 | "api_key": { 10 | "location": "query", 11 | "name": "apikey", 12 | "prefix": null 13 | } 14 | }, 15 | "default_security_credentials_by_scheme": {}, 16 | "categories": [ 17 | "Search & Scraping" 18 | ], 19 | "visibility": "public", 20 | "active": true 21 | } 22 | -------------------------------------------------------------------------------- /backend/apps/zoho_desk/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ZOHO_DESK", 3 | "display_name": "Zoho Desk", 4 | "logo": "https://raw.githubusercontent.com/aipotheosis-labs/aipolabs-icons/refs/heads/main/apps/zoho_desk.svg", 5 | "provider": "Zoho", 6 | "version": "1.0", 7 | "description": "Zoho Desk API integration for customer support and ticket management. Provides access to tickets, contacts, departments, and customer support features.", 8 | "security_schemes": { 9 | "oauth2": { 10 | "location": "header", 11 | "name": "Authorization", 12 | "prefix": "Zoho-oauthtoken", 13 | "client_id": "{{ AIPOLABS_ZOHO_APP_CLIENT_ID }}", 14 | "client_secret": "{{ AIPOLABS_ZOHO_APP_CLIENT_SECRET }}", 15 | "scope": "Desk.tickets.ALL,Desk.tickets.READ,Desk.tickets.WRITE,Desk.tickets.UPDATE,Desk.tickets.CREATE,Desk.tickets.DELETE,Desk.contacts.READ,Desk.contacts.WRITE,Desk.contacts.UPDATE,Desk.contacts.CREATE,Desk.tasks.ALL,Desk.tasks.WRITE,Desk.tasks.READ,Desk.tasks.CREATE,Desk.tasks.UPDATE,Desk.tasks.DELETE,Desk.basic.READ,Desk.basic.CREATE,Desk.settings.ALL,Desk.settings.WRITE,Desk.settings.READ,Desk.settings.CREATE,Desk.settings.UPDATE,Desk.settings.DELETE,Desk.search.READ,Desk.events.ALL,Desk.events.READ,Desk.events.WRITE,Desk.events.CREATE,Desk.events.UPDATE,Desk.events.DELETE,Desk.articles.READ,Desk.articles.CREATE,Desk.articles.UPDATE,Desk.articles.DELETE", 16 | "authorize_url": "https://accounts.zoho.com/oauth/v2/auth", 17 | "access_token_url": "https://accounts.zoho.com/oauth/v2/token", 18 | "refresh_token_url": "https://accounts.zoho.com/oauth/v2/token" 19 | } 20 | }, 21 | "default_security_credentials_by_scheme": {}, 22 | "categories": [ 23 | "CRM & Support" 24 | ], 25 | "visibility": "public", 26 | "active": true 27 | } 28 | -------------------------------------------------------------------------------- /backend/compose.ci.yml: -------------------------------------------------------------------------------- 1 | services: 2 | # Override the runner service in compose.yml to use the CI environment variables 3 | # to run tests 4 | server: 5 | environment: 6 | - SERVER_OPENAI_API_KEY=${SERVER_OPENAI_API_KEY?} 7 | - CLI_OPENAI_API_KEY=${CLI_OPENAI_API_KEY?} 8 | test-runner: 9 | environment: 10 | - SERVER_OPENAI_API_KEY=${SERVER_OPENAI_API_KEY?} 11 | - CLI_OPENAI_API_KEY=${CLI_OPENAI_API_KEY?} 12 | command: > 13 | /bin/sh -c "alembic upgrade head && uv run pytest" 14 | -------------------------------------------------------------------------------- /backend/deployment/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Welcome to your CDK Python project! 3 | 4 | This is a blank project for CDK development with Python. 5 | 6 | The `cdk.json` file tells the CDK Toolkit how to execute your app. 7 | 8 | This project is set up like a standard Python project. The initialization 9 | process also creates a virtualenv within this project, stored under the `.venv` 10 | directory. To create the virtualenv it assumes that there is a `python3` 11 | (or `python` for Windows) executable in your path with access to the `venv` 12 | package. If for any reason the automatic creation of the virtualenv fails, 13 | you can create the virtualenv manually. 14 | 15 | To manually create a virtualenv on MacOS and Linux: 16 | 17 | ``` 18 | $ python3 -m venv .venv 19 | ``` 20 | 21 | After the init process completes and the virtualenv is created, you can use the following 22 | step to activate your virtualenv. 23 | 24 | ``` 25 | $ source .venv/bin/activate 26 | ``` 27 | 28 | If you are a Windows platform, you would activate the virtualenv like this: 29 | 30 | ``` 31 | % .venv\Scripts\activate.bat 32 | ``` 33 | 34 | Once the virtualenv is activated, you can install the required dependencies. 35 | 36 | ``` 37 | $ pip install -r requirements.txt 38 | ``` 39 | 40 | At this point you can now synthesize the CloudFormation template for this code. 41 | 42 | ``` 43 | $ cdk synth 44 | ``` 45 | 46 | To add additional dependencies, for example other CDK libraries, just add 47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt` 48 | command. 49 | 50 | ## Useful commands 51 | 52 | * `cdk ls` list all stacks in the app 53 | * `cdk synth` emits the synthesized CloudFormation template 54 | * `cdk deploy` deploy this stack to your default AWS account/region 55 | * `cdk diff` compare deployed stack with current state 56 | * `cdk docs` open CDK documentation 57 | 58 | Enjoy! 59 | -------------------------------------------------------------------------------- /backend/deployment/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # import os 3 | 4 | import aws_cdk as cdk 5 | from provision.provision_stack import ProvisionStack 6 | 7 | app = cdk.App() 8 | ProvisionStack( 9 | app, 10 | "ProvisionStack", 11 | # If you don't specify 'env', this stack will be environment-agnostic. 12 | # Account/Region-dependent features and context lookups will not work, 13 | # but a single synthesized template can be deployed anywhere. 14 | # Uncomment the next line to specialize this stack for the AWS Account 15 | # and Region that are implied by the current CLI configuration. 16 | # env=cdk.Environment( 17 | # account=os.getenv('CDK_DEFAULT_ACCOUNT'), 18 | # region=os.getenv('CDK_DEFAULT_REGION') 19 | # ), 20 | # Uncomment the next line if you know exactly what Account and Region you 21 | # want to deploy the stack to. */ 22 | # env=cdk.Environment(account='123456789012', region='us-east-1'), 23 | # For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html 24 | ) 25 | 26 | app.synth() 27 | -------------------------------------------------------------------------------- /backend/deployment/provision/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/deployment/provision/__init__.py -------------------------------------------------------------------------------- /backend/deployment/provision/provision_stack.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | from aws_cdk import Stack # Duration,; aws_sqs as sqs, 4 | from constructs import Construct 5 | 6 | 7 | class ProvisionStack(Stack): 8 | def __init__(self, scope: Construct, construct_id: str, **kwargs: dict[str, Any]) -> None: 9 | pass 10 | # super().__init__(scope, construct_id, **kwargs) 11 | 12 | # The code that defines your stack goes here 13 | 14 | # example resource 15 | # queue = sqs.Queue( 16 | # self, "ProvisionQueue", 17 | # visibility_timeout=Duration.seconds(300), 18 | # ) 19 | -------------------------------------------------------------------------------- /backend/deployment/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/deployment/tests/__init__.py -------------------------------------------------------------------------------- /backend/deployment/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/deployment/tests/unit/__init__.py -------------------------------------------------------------------------------- /backend/deployment/tests/unit/test_provision_stack.py: -------------------------------------------------------------------------------- 1 | # import aws_cdk as core 2 | # import aws_cdk.assertions as assertions 3 | # from provision.provision_stack import ProvisionStack 4 | 5 | 6 | # # example tests. To run these tests, uncomment this file along with the example 7 | # # resource in provision/provision_stack.py 8 | # def test_sqs_queue_created() -> None: 9 | # app = core.App() 10 | # stack = ProvisionStack(app, "provision") 11 | # template = assertions.Template.from_stack(stack) 12 | 13 | # template.has_resource_properties("AWS::SQS::Queue", {"VisibilityTimeout": 300}) 14 | -------------------------------------------------------------------------------- /backend/evals/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/evals/__init__.py -------------------------------------------------------------------------------- /backend/evals/intent_prompts.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | 3 | 4 | def task_prompt(row: pd.Series) -> str: 5 | """Generate a task-oriented intent prompt.""" 6 | return f""" 7 | You are simulating realistic user intents for a software platform with many apps and functions. The user knows they want to use the app called "{row["app_name"]}", which is used for {row["app_description"]}. One of the available functions is: 8 | 9 | Function Name: {row["function_name"]} 10 | Function Description: {row["function_description"]} 11 | 12 | Simulate a user intent where the user only knows they want to use the {row["app_name"]} app, and they have a goal that can be fulfilled by the function above. Do not mention the function name but mention the app name. The intent should be phrased as a task the user wants to accomplish, not a question. Be natural and goal-oriented. 13 | Format: You should only return the intent, nothing else. 14 | """.strip() 15 | 16 | 17 | # Dictionary of all available prompts 18 | PROMPTS = { 19 | "task": task_prompt, 20 | } 21 | -------------------------------------------------------------------------------- /backend/images/propelauth-switch-to-local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/backend/images/propelauth-switch-to-local.png -------------------------------------------------------------------------------- /backend/scripts/create-kms-encryption-key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script is mounted into the localstack container to run during its container 3 | # startup. 4 | # This command creates a KMS key in the aws localstack container with an id of 5 | # 00000000-0000-0000-0000-000000000001. This key is used as the key encryption 6 | # key in local docker compose environment for the common/encryption.py module. 7 | # Using fixed custom key material ensures the same key is generated each time 8 | 9 | FIXED_KEY_MATERIAL="U2FsdGVkX1+K8yfnrMn+QRyh2nWPfI9wXA84BGm6YAA=" 10 | awslocal kms create-key --region us-east-2 --tags '[{"TagKey":"_custom_id_","TagValue":"00000000-0000-0000-0000-000000000001"},{"TagKey":"_custom_key_material_","TagValue":"'"$FIXED_KEY_MATERIAL"'"}]' 11 | -------------------------------------------------------------------------------- /frontend/.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_API_URL=http://localhost:8000 2 | NEXT_PUBLIC_DEV_PORTAL_URL=http://localhost:3000 3 | NEXT_PUBLIC_ENVIRONMENT=local 4 | NEXT_PUBLIC_AUTH_URL=http://localhost:12800 5 | -------------------------------------------------------------------------------- /frontend/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | 43 | tmp/ 44 | 45 | # Sentry Config File 46 | .env.sentry-build-plugin 47 | 48 | .vscode 49 | .idea 50 | -------------------------------------------------------------------------------- /frontend/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | build 4 | dist 5 | ui/ 6 | -------------------------------------------------------------------------------- /frontend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": false, 4 | "trailingComma": "all", 5 | "printWidth": 80, 6 | "tabWidth": 2 7 | } 8 | -------------------------------------------------------------------------------- /frontend/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } 22 | -------------------------------------------------------------------------------- /frontend/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ]; 15 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /frontend/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /frontend/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/frontend/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /frontend/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/frontend/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /frontend/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/frontend/public/apple-touch-icon.png -------------------------------------------------------------------------------- /frontend/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/frontend/public/favicon-16x16.png -------------------------------------------------------------------------------- /frontend/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/frontend/public/favicon-32x32.png -------------------------------------------------------------------------------- /frontend/public/favicon-dark.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/frontend/public/favicon-dark.ico -------------------------------------------------------------------------------- /frontend/public/favicon-light.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/frontend/public/favicon-light.ico -------------------------------------------------------------------------------- /frontend/public/icon/google.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /frontend/public/umcp-demo-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aipotheosis-labs/aci/62384cbbc420b6d6fa30845a0ea77a778d2480ba/frontend/public/umcp-demo-thumbnail.png -------------------------------------------------------------------------------- /frontend/sentry.client.config.ts: -------------------------------------------------------------------------------- 1 | // This file configures the initialization of Sentry on the client. 2 | // The config you add here will be used whenever a users loads a page in their browser. 3 | // https://docs.sentry.io/platforms/javascript/guides/nextjs/ 4 | 5 | import * as Sentry from "@sentry/nextjs"; 6 | import { SentryOptions } from "./sentryoptions"; 7 | 8 | if ( 9 | process.env.NEXT_PUBLIC_ENVIRONMENT && 10 | process.env.NEXT_PUBLIC_ENVIRONMENT !== "local" 11 | ) { 12 | Sentry.init({ 13 | dsn: "https://2ec877a53cbd31d24690cc4cb1828457@o4508859021459456.ingest.us.sentry.io/4508859022376960", 14 | 15 | environment: process.env.NEXT_PUBLIC_ENVIRONMENT, 16 | 17 | // Add optional integrations for additional features 18 | integrations: [Sentry.replayIntegration()], 19 | 20 | // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. 21 | tracesSampleRate: 22 | SentryOptions[ 23 | process.env.NEXT_PUBLIC_ENVIRONMENT as "development" | "production" 24 | ].tracesSampleRate, 25 | 26 | // Define how likely Replay events are sampled. 27 | // This sets the sample rate to be 10%. You may want this to be 100% while 28 | // in development and sample at a lower rate in production 29 | replaysSessionSampleRate: 30 | SentryOptions[ 31 | process.env.NEXT_PUBLIC_ENVIRONMENT as "development" | "production" 32 | ].replaysSessionSampleRate, 33 | 34 | // Define how likely Replay events are sampled when an error occurs. 35 | replaysOnErrorSampleRate: 36 | SentryOptions[ 37 | process.env.NEXT_PUBLIC_ENVIRONMENT as "development" | "production" 38 | ].replaysOnErrorSampleRate, 39 | 40 | // Setting this option to true will print useful information to the console while you're setting up Sentry. 41 | debug: false, 42 | }); 43 | } 44 | -------------------------------------------------------------------------------- /frontend/sentry.edge.config.ts: -------------------------------------------------------------------------------- 1 | // This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on). 2 | // The config you add here will be used whenever one of the edge features is loaded. 3 | // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally. 4 | // https://docs.sentry.io/platforms/javascript/guides/nextjs/ 5 | 6 | import * as Sentry from "@sentry/nextjs"; 7 | import { SentryOptions } from "./sentryoptions"; 8 | 9 | if ( 10 | process.env.NEXT_PUBLIC_ENVIRONMENT && 11 | process.env.NEXT_PUBLIC_ENVIRONMENT !== "local" 12 | ) { 13 | Sentry.init({ 14 | dsn: "https://2ec877a53cbd31d24690cc4cb1828457@o4508859021459456.ingest.us.sentry.io/4508859022376960", 15 | 16 | // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. 17 | tracesSampleRate: 18 | SentryOptions[ 19 | process.env.NEXT_PUBLIC_ENVIRONMENT as "development" | "production" 20 | ].tracesSampleRate, 21 | 22 | // Setting this option to true will print useful information to the console while you're setting up Sentry. 23 | debug: false, 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /frontend/sentry.server.config.ts: -------------------------------------------------------------------------------- 1 | // This file configures the initialization of Sentry on the server. 2 | // The config you add here will be used whenever the server handles a request. 3 | // https://docs.sentry.io/platforms/javascript/guides/nextjs/ 4 | 5 | import * as Sentry from "@sentry/nextjs"; 6 | import { SentryOptions } from "./sentryoptions"; 7 | 8 | if ( 9 | process.env.NEXT_PUBLIC_ENVIRONMENT && 10 | process.env.NEXT_PUBLIC_ENVIRONMENT !== "local" 11 | ) { 12 | Sentry.init({ 13 | dsn: "https://2ec877a53cbd31d24690cc4cb1828457@o4508859021459456.ingest.us.sentry.io/4508859022376960", 14 | 15 | // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. 16 | tracesSampleRate: 17 | SentryOptions[ 18 | process.env.NEXT_PUBLIC_ENVIRONMENT as "development" | "production" 19 | ].tracesSampleRate, 20 | 21 | // Setting this option to true will print useful information to the console while you're setting up Sentry. 22 | debug: false, 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /frontend/sentryoptions.ts: -------------------------------------------------------------------------------- 1 | export const SentryOptions = { 2 | development: { 3 | tracesSampleRate: 1, 4 | replaysSessionSampleRate: 1, 5 | replaysOnErrorSampleRate: 1, 6 | }, 7 | production: { 8 | tracesSampleRate: 0.1, 9 | replaysSessionSampleRate: 0.1, 10 | replaysOnErrorSampleRate: 1, 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /frontend/src/app/apps/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { AppGrid } from "@/components/apps/app-grid"; 4 | import { Separator } from "@/components/ui/separator"; 5 | import { useApps } from "@/hooks/use-app"; 6 | import { AlertCircle, Loader2 } from "lucide-react"; 7 | 8 | export default function AppStorePage() { 9 | // TODO: implement pagination once we have a lot of apps 10 | const { data: apps, isPending, isError } = useApps([]); 11 | 12 | return ( 13 |
14 |
15 |

App Store

16 |

17 | Browse and connect with your favorite apps and tools. 18 |

19 |
20 | 21 | 22 |
23 | {isPending ? ( 24 |
25 | 26 | Loading apps... 27 |
28 | ) : isError ? ( 29 |
30 | 31 | Failed to load apps. Please try to refresh the page. 32 |
33 | ) : ( 34 | 35 | )} 36 |
37 |
38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /frontend/src/app/global-error.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as Sentry from "@sentry/nextjs"; 4 | import NextError from "next/error"; 5 | import { useEffect } from "react"; 6 | 7 | export default function GlobalError({ 8 | error, 9 | }: { 10 | error: Error & { digest?: string }; 11 | }) { 12 | useEffect(() => { 13 | Sentry.captureException(error); 14 | }, [error]); 15 | 16 | return ( 17 | 18 | 19 | {/* `NextError` is the default Next.js error page component. Its type 20 | definition requires a `statusCode` prop. However, since the App Router 21 | does not expose status codes for errors, we simply pass 0 to render a 22 | generic error message. */} 23 | 24 | 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /frontend/src/app/playground/code-block.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | interface CodeBlockProps { 4 | inline: boolean; 5 | className: string; 6 | children: React.ReactNode; 7 | } 8 | 9 | export function CodeBlock({ 10 | inline, 11 | className, 12 | children, 13 | ...props 14 | }: CodeBlockProps) { 15 | if (!inline) { 16 | return ( 17 |
18 |
22 |           {children}
23 |         
24 |
25 | ); 26 | } else { 27 | return ( 28 | 32 | {children} 33 | 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /frontend/src/app/playground/function-calling.tsx: -------------------------------------------------------------------------------- 1 | import { useToolExecution } from "@/hooks/use-tool-execution"; 2 | import type { ToolInvocation } from "ai"; 3 | 4 | type FunctionCallingProps = { 5 | toolInvocation: ToolInvocation; 6 | linkedAccountOwnerId: string; 7 | apiKey: string; 8 | addToolResult: ({ 9 | toolCallId, 10 | result, 11 | }: { 12 | toolCallId: string; 13 | result: object; 14 | }) => void; 15 | }; 16 | 17 | export function FunctionCalling({ 18 | toolInvocation, 19 | linkedAccountOwnerId, 20 | apiKey, 21 | addToolResult, 22 | }: FunctionCallingProps) { 23 | const { toolName } = toolInvocation; 24 | 25 | const { error } = useToolExecution({ 26 | toolInvocation, 27 | addToolResult, 28 | linkedAccountOwnerId, 29 | apiKey, 30 | }); 31 | 32 | if (error) { 33 | return
Function Calling Error: {error}
; 34 | } 35 | 36 | return ( 37 |
38 |
39 | Function Calling: {toolName} 40 |
41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /frontend/src/app/playground/overview.tsx: -------------------------------------------------------------------------------- 1 | import * as motion from "motion/react-client"; 2 | import Image from "next/image"; 3 | 4 | export const Overview = () => { 5 | return ( 6 | 14 |
15 |

16 | ACI.dev Logo 23 |

24 |

25 | Hi, Agent Builder 26 |

27 |

28 | How can I help you today? 29 |

30 |
31 |
32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /frontend/src/app/playground/use-scroll-to-bottom.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, type RefObject } from "react"; 2 | import { Message } from "ai"; 3 | export function useScrollToBottom( 4 | messages?: Message[], 5 | ): [RefObject, RefObject] { 6 | const containerRef = useRef(null); 7 | const endRef = useRef(null); 8 | 9 | useEffect(() => { 10 | const end = endRef.current; 11 | if (end) { 12 | end.scrollIntoView({ behavior: "instant", block: "end" }); 13 | } 14 | }, [messages]); 15 | 16 | return [containerRef, endRef]; 17 | } 18 | -------------------------------------------------------------------------------- /frontend/src/components/apps/configure-app/stepper.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | import { Progress } from "@/components/ui/progress"; 3 | import { FaCheck } from "react-icons/fa6"; 4 | 5 | interface StepperProps { 6 | currentStep: number; 7 | totalSteps: number; 8 | steps: { id: number; title: string }[]; 9 | } 10 | 11 | export function Stepper({ currentStep, totalSteps, steps }: StepperProps) { 12 | return ( 13 |
14 |
15 | {steps.map((step) => ( 16 |
17 |
step.id 23 | ? "bg-[#1CD1AF] text-white" 24 | : "bg-muted text-muted-foreground", 25 | )} 26 | > 27 | {currentStep > step.id ? ( 28 | 29 | ) : ( 30 | step.id 31 | )} 32 |
33 | 34 | {step.title} 35 | 36 |
37 | ))} 38 | 39 |
40 | 44 |
45 |
46 |
47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /frontend/src/components/apps/useAgentColumns.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useMemo } from "react"; 4 | import { IdDisplay } from "@/components/apps/id-display"; 5 | import { createColumnHelper, type ColumnDef } from "@tanstack/react-table"; 6 | import { Agent } from "@/lib/types/project"; 7 | import { Button } from "@/components/ui/button"; 8 | import { ArrowUpDown } from "lucide-react"; 9 | 10 | const columnHelper = createColumnHelper(); 11 | 12 | export const useAgentColumns = (): ColumnDef[] => { 13 | return useMemo(() => { 14 | const columns = [ 15 | columnHelper.accessor("name", { 16 | header: ({ column }) => ( 17 |
18 | 31 |
32 | ), 33 | cell: (info) => , 34 | enableGlobalFilter: true, 35 | id: "name", 36 | }), 37 | columnHelper.accessor("description", { 38 | header: () => "Description", 39 | cell: (info) =>
{info.getValue()}
, 40 | enableGlobalFilter: true, 41 | }), 42 | ]; 43 | 44 | return columns as ColumnDef[]; 45 | }, []); 46 | }; 47 | -------------------------------------------------------------------------------- /frontend/src/components/home/code-block.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | import { BiCopy } from "react-icons/bi"; 5 | import { BsCheckLg } from "react-icons/bs"; 6 | import { toast } from "sonner"; 7 | 8 | interface CodeBlockProps { 9 | code: string; 10 | } 11 | 12 | export function CodeBlock({ code }: CodeBlockProps) { 13 | const [copied, setCopied] = React.useState(false); 14 | 15 | const copyToClipboard = async () => { 16 | try { 17 | await navigator.clipboard.writeText(code); 18 | setCopied(true); 19 | toast.success("Code copied to clipboard"); 20 | setTimeout(() => setCopied(false), 2000); 21 | } catch (err) { 22 | console.error("Copy failed:", err); 23 | toast.error("Failed to copy code"); 24 | } 25 | }; 26 | 27 | return ( 28 |
29 | 40 |
41 |         {code}
42 |       
43 |
44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /frontend/src/components/layout/footer.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | export const Footer = () => { 3 | return
; 4 | }; 5 | -------------------------------------------------------------------------------- /frontend/src/components/playground/beta-alert.tsx: -------------------------------------------------------------------------------- 1 | import { Alert, AlertDescription } from "@/components/ui/alert"; 2 | import { X } from "lucide-react"; 3 | import { useState } from "react"; 4 | import { cn } from "@/lib/utils"; 5 | 6 | export const BetaAlert = () => { 7 | const [visible, setVisible] = useState(true); 8 | if (!visible) return null; 9 | 10 | return ( 11 | 18 | 19 | Agent Playground is a beta feature and not recommended for production 20 | use. Expect limited stability and possible changes. 21 | 22 | 23 | 30 | 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /frontend/src/components/stats/stats-bar.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react"; 2 | import { cn } from "@/lib/utils"; 3 | 4 | interface StatsContainerProps { 5 | children: ReactNode; 6 | className?: string; 7 | } 8 | 9 | export function StatsContainer({ children, className }: StatsContainerProps) { 10 | return ( 11 |
12 |
13 | {Array.isArray(children) 14 | ? children.map((child, index) => ( 15 |
23 | {child} 24 |
25 | )) 26 | : children} 27 |
28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /frontend/src/components/stats/stats-card.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | import { TrendingDown, TrendingUp } from "lucide-react"; 3 | import { HelpCircle } from "lucide-react"; 4 | 5 | interface StatsCardProps { 6 | title: string; 7 | value: number; 8 | percentageChange: number; 9 | valuePrefix?: string; 10 | valueSuffix?: string; 11 | className?: string; 12 | } 13 | 14 | export function StatsCard({ 15 | title, 16 | value, 17 | percentageChange, 18 | valuePrefix = "", 19 | valueSuffix = "", 20 | className, 21 | }: StatsCardProps) { 22 | const isPositive = percentageChange >= 0; 23 | 24 | return ( 25 |
26 |
27 | {title} 28 | 29 |
30 |
31 |
32 | {valuePrefix} 33 | {value.toLocaleString()} 34 | {valueSuffix} 35 |
36 |
42 | {isPositive ? ( 43 | 44 | ) : ( 45 | 46 | )} 47 | {Math.abs(percentageChange)}% since last month 48 |
49 |
50 |
51 | ); 52 | } 53 | -------------------------------------------------------------------------------- /frontend/src/components/ui-extensions/enhanced-data-table/column-filter.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { Column } from "@tanstack/react-table"; 4 | import { 5 | Select, 6 | SelectContent, 7 | SelectItem, 8 | SelectTrigger, 9 | SelectValue, 10 | } from "@/components/ui/select"; 11 | import { useEffect, useState } from "react"; 12 | interface ColumnFilterProps { 13 | column: Column; 14 | options: string[]; 15 | } 16 | 17 | export function ColumnFilter({ 18 | column, 19 | options, 20 | }: ColumnFilterProps) { 21 | const [selectedValue, setSelectedValue] = useState("_all_"); 22 | 23 | useEffect(() => { 24 | const filterValue = column.getFilterValue() as string; 25 | if (filterValue) { 26 | setSelectedValue(filterValue); 27 | } 28 | }, [column]); 29 | 30 | return ( 31 | 50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /frontend/src/components/ui-extensions/enhanced-data-table/row-selection-column.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { createColumnHelper, type ColumnDef } from "@tanstack/react-table"; 4 | import { Checkbox } from "@/components/ui/checkbox"; 5 | 6 | export function getRowSelectionColumn(): ColumnDef { 7 | const columnHelper = createColumnHelper(); 8 | return columnHelper.display({ 9 | id: "select", 10 | header: ({ table }) => ( 11 |
12 | { 18 | table.toggleAllRowsSelected(Boolean(value)); 19 | }} 20 | aria-label="Select all" 21 | /> 22 |
23 | ), 24 | cell: ({ row }) => ( 25 |
26 | { 29 | row.toggleSelected(Boolean(value)); 30 | }} 31 | /> 32 |
33 | ), 34 | }); 35 | } 36 | -------------------------------------------------------------------------------- /frontend/src/components/ui/alert.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const alertVariants = cva( 7 | "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7", 8 | { 9 | variants: { 10 | variant: { 11 | default: "bg-background text-foreground", 12 | destructive: 13 | "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", 14 | }, 15 | }, 16 | defaultVariants: { 17 | variant: "default", 18 | }, 19 | } 20 | ) 21 | 22 | const Alert = React.forwardRef< 23 | HTMLDivElement, 24 | React.HTMLAttributes & VariantProps 25 | >(({ className, variant, ...props }, ref) => ( 26 |
32 | )) 33 | Alert.displayName = "Alert" 34 | 35 | const AlertTitle = React.forwardRef< 36 | HTMLParagraphElement, 37 | React.HTMLAttributes 38 | >(({ className, ...props }, ref) => ( 39 |
44 | )) 45 | AlertTitle.displayName = "AlertTitle" 46 | 47 | const AlertDescription = React.forwardRef< 48 | HTMLParagraphElement, 49 | React.HTMLAttributes 50 | >(({ className, ...props }, ref) => ( 51 |
56 | )) 57 | AlertDescription.displayName = "AlertDescription" 58 | 59 | export { Alert, AlertTitle, AlertDescription } 60 | -------------------------------------------------------------------------------- /frontend/src/components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const badgeVariants = cva( 7 | "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", 8 | { 9 | variants: { 10 | variant: { 11 | default: 12 | "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80", 13 | secondary: 14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", 15 | destructive: 16 | "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80", 17 | outline: "text-foreground", 18 | }, 19 | }, 20 | defaultVariants: { 21 | variant: "default", 22 | }, 23 | } 24 | ) 25 | 26 | export interface BadgeProps 27 | extends React.HTMLAttributes, 28 | VariantProps {} 29 | 30 | function Badge({ className, variant, ...props }: BadgeProps) { 31 | return ( 32 |
33 | ) 34 | } 35 | 36 | export { Badge, badgeVariants } 37 | -------------------------------------------------------------------------------- /frontend/src/components/ui/checkbox.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as CheckboxPrimitive from "@radix-ui/react-checkbox" 5 | import { Check } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const Checkbox = React.forwardRef< 10 | React.ElementRef, 11 | React.ComponentPropsWithoutRef 12 | >(({ className, ...props }, ref) => ( 13 | 21 | 24 | 25 | 26 | 27 | )) 28 | Checkbox.displayName = CheckboxPrimitive.Root.displayName 29 | 30 | export { Checkbox } 31 | -------------------------------------------------------------------------------- /frontend/src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Input = React.forwardRef>( 6 | ({ className, type, ...props }, ref) => { 7 | return ( 8 | 17 | ) 18 | } 19 | ) 20 | Input.displayName = "Input" 21 | 22 | export { Input } 23 | -------------------------------------------------------------------------------- /frontend/src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /frontend/src/components/ui/popover.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as PopoverPrimitive from "@radix-ui/react-popover" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Popover = PopoverPrimitive.Root 9 | 10 | const PopoverTrigger = PopoverPrimitive.Trigger 11 | 12 | const PopoverAnchor = PopoverPrimitive.Anchor 13 | 14 | const PopoverContent = React.forwardRef< 15 | React.ElementRef, 16 | React.ComponentPropsWithoutRef 17 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 18 | 19 | 29 | 30 | )) 31 | PopoverContent.displayName = PopoverPrimitive.Content.displayName 32 | 33 | export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } 34 | -------------------------------------------------------------------------------- /frontend/src/components/ui/progress.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ProgressPrimitive from "@radix-ui/react-progress" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Progress = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, value, ...props }, ref) => ( 12 | 20 | 24 | 25 | )) 26 | Progress.displayName = ProgressPrimitive.Root.displayName 27 | 28 | export { Progress } 29 | -------------------------------------------------------------------------------- /frontend/src/components/ui/scroll-area.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const ScrollArea = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, children, ...props }, ref) => ( 12 | 17 | 18 | {children} 19 | 20 | 21 | 22 | 23 | )) 24 | ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName 25 | 26 | const ScrollBar = React.forwardRef< 27 | React.ElementRef, 28 | React.ComponentPropsWithoutRef 29 | >(({ className, orientation = "vertical", ...props }, ref) => ( 30 | 43 | 44 | 45 | )) 46 | ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName 47 | 48 | export { ScrollArea, ScrollBar } 49 | -------------------------------------------------------------------------------- /frontend/src/components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Separator = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >( 12 | ( 13 | { className, orientation = "horizontal", decorative = true, ...props }, 14 | ref 15 | ) => ( 16 | 27 | ) 28 | ) 29 | Separator.displayName = SeparatorPrimitive.Root.displayName 30 | 31 | export { Separator } 32 | -------------------------------------------------------------------------------- /frontend/src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /frontend/src/components/ui/sonner.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { useTheme } from "next-themes" 4 | import { Toaster as Sonner } from "sonner" 5 | 6 | type ToasterProps = React.ComponentProps 7 | 8 | const Toaster = ({ ...props }: ToasterProps) => { 9 | const { theme = "system" } = useTheme() 10 | 11 | return ( 12 | 28 | ) 29 | } 30 | 31 | export { Toaster } 32 | -------------------------------------------------------------------------------- /frontend/src/components/ui/switch.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SwitchPrimitives from "@radix-ui/react-switch" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Switch = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, ...props }, ref) => ( 12 | 20 | 25 | 26 | )) 27 | Switch.displayName = SwitchPrimitives.Root.displayName 28 | 29 | export { Switch } 30 | -------------------------------------------------------------------------------- /frontend/src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Textarea = React.forwardRef< 6 | HTMLTextAreaElement, 7 | React.ComponentProps<"textarea"> 8 | >(({ className, ...props }, ref) => { 9 | return ( 10 |