From 86286e1ac8c1a6617d8a846d0f958a41ee8d259b Mon Sep 17 00:00:00 2001 From: Yeuoly <45712896+Yeuoly@users.noreply.github.com> Date: Tue, 23 Jan 2024 19:58:23 +0800 Subject: [PATCH] Feat/assistant app (#2086) Co-authored-by: chenhe Co-authored-by: Pascal M <11357019+perzeuss@users.noreply.github.com> --- .github/workflows/tool-tests.yaml | 26 + CONTRIBUTING.md | 2 + api/app.py | 2 +- api/commands.py | 63 +- api/controllers/console/__init__.py | 2 - api/controllers/console/app/app.py | 29 +- .../console/explore/installed_app.py | 5 +- api/controllers/console/explore/message.py | 6 +- api/controllers/console/explore/parameter.py | 43 +- .../console/explore/recommended_app.py | 4 +- .../console/universal_chat/audio.py | 2 - .../console/universal_chat/chat.py | 120 ---- .../console/universal_chat/conversation.py | 110 ---- .../console/universal_chat/message.py | 145 ----- .../console/universal_chat/parameter.py | 38 -- .../console/universal_chat/wraps.py | 86 --- .../console/workspace/tool_providers.py | 343 ++++++++--- api/controllers/files/__init__.py | 1 + api/controllers/files/tool_files.py | 47 ++ api/controllers/service_api/app/app.py | 44 +- api/controllers/service_api/app/message.py | 16 +- api/controllers/web/app.py | 44 +- api/controllers/web/message.py | 4 +- api/core/agent/agent_executor.py | 4 +- api/core/app_runner/agent_app_runner.py | 251 -------- api/core/app_runner/app_runner.py | 128 +++- api/core/app_runner/assistant_app_runner.py | 342 +++++++++++ api/core/app_runner/basic_app_runner.py | 112 +--- api/core/app_runner/generate_task_pipeline.py | 49 +- api/core/application_manager.py | 180 ++++-- api/core/application_queue_manager.py | 27 +- .../agent_tool_callback_handler.py | 74 +++ api/core/entities/application_entities.py | 40 +- api/core/entities/queue_entities.py | 19 +- api/core/features/agent_runner.py | 148 +---- api/core/features/assistant_base_runner.py | 558 +++++++++++++++++ api/core/features/assistant_cot_runner.py | 578 ++++++++++++++++++ api/core/features/assistant_fc_runner.py | 335 ++++++++++ api/core/features/dataset_retrieval.py | 4 +- api/core/file/file_obj.py | 11 + api/core/file/message_file_parser.py | 5 +- api/core/file/tool_file_parser.py | 8 + .../model_providers/openai/llm/llm.py | 20 +- api/core/tools/README.md | 25 + api/core/tools/README_CN.md | 27 + .../tools/docs/en_US/advanced_scale_out.md | 266 ++++++++ api/core/tools/docs/en_US/tool_scale_out.md | 212 +++++++ .../tools/docs/zh_Hans/advanced_scale_out.md | 266 ++++++++ .../docs/zh_Hans/images/index/image-1.png | Bin 0 -> 248210 bytes .../docs/zh_Hans/images/index/image-2.png | Bin 0 -> 416650 bytes .../tools/docs/zh_Hans/images/index/image.png | Bin 0 -> 272811 bytes api/core/tools/docs/zh_Hans/tool_scale_out.md | 212 +++++++ api/core/tools/entities/common_entities.py | 22 + api/core/tools/entities/constant.py | 3 + api/core/tools/entities/tool_bundle.py | 34 ++ api/core/tools/entities/tool_entities.py | 305 +++++++++ api/core/tools/entities/user_entities.py | 48 ++ api/core/tools/errors.py | 20 + api/core/tools/model/errors.py | 2 + api/core/tools/model/tool_model_manager.py | 174 ++++++ api/core/tools/prompt/template.py | 102 ++++ api/core/tools/provider/api_tool_provider.py | 169 +++++ api/core/tools/provider/app_tool_provider.py | 116 ++++ api/core/tools/provider/builtin/__init__.py | 0 api/core/tools/provider/builtin/_positions.py | 26 + .../provider/builtin/chart/_assets/icon.png | Bin 0 -> 1363 bytes .../tools/provider/builtin/chart/chart.py | 24 + .../tools/provider/builtin/chart/chart.yaml | 11 + .../tools/provider/builtin/chart/tools/bar.py | 47 ++ .../provider/builtin/chart/tools/bar.yaml | 35 ++ .../provider/builtin/chart/tools/line.py | 49 ++ .../provider/builtin/chart/tools/line.yaml | 35 ++ .../tools/provider/builtin/chart/tools/pie.py | 46 ++ .../provider/builtin/chart/tools/pie.yaml | 35 ++ .../tools/provider/builtin/dalle/__init__.py | 0 .../provider/builtin/dalle/_assets/icon.png | Bin 0 -> 156474 bytes .../tools/provider/builtin/dalle/dalle.py | 23 + .../tools/provider/builtin/dalle/dalle.yaml | 47 ++ .../provider/builtin/dalle/tools/dalle2.py | 66 ++ .../provider/builtin/dalle/tools/dalle2.yaml | 63 ++ .../provider/builtin/dalle/tools/dalle3.py | 74 +++ .../provider/builtin/dalle/tools/dalle3.yaml | 103 ++++ .../provider/builtin/google/_assets/icon.svg | 6 + .../tools/provider/builtin/google/google.py | 23 + .../tools/provider/builtin/google/google.yaml | 24 + .../builtin/google/tools/google_search.py | 163 +++++ .../builtin/google/tools/google_search.yaml | 43 ++ .../builtin/stablediffusion/_assets/icon.png | Bin 0 -> 16324 bytes .../stablediffusion/stablediffusion.py | 26 + .../stablediffusion/stablediffusion.yaml | 29 + .../stablediffusion/tools/stable_diffusion.py | 244 ++++++++ .../tools/stable_diffusion.yaml | 77 +++ .../provider/builtin/time/_assets/icon.svg | 3 + api/core/tools/provider/builtin/time/time.py | 16 + .../tools/provider/builtin/time/time.yaml | 11 + .../builtin/time/tools/current_time.py | 17 + .../builtin/time/tools/current_time.yaml | 12 + .../builtin/vectorizer/_assets/icon.png | Bin 0 -> 1875 bytes .../builtin/vectorizer/tools/test_data.py | 1 + .../builtin/vectorizer/tools/vectorizer.py | 74 +++ .../builtin/vectorizer/tools/vectorizer.yaml | 32 + .../provider/builtin/vectorizer/vectorizer.py | 23 + .../builtin/vectorizer/vectorizer.yaml | 36 ++ .../builtin/webscraper/_assets/icon.svg | 3 + .../builtin/webscraper/tools/webscraper.py | 28 + .../builtin/webscraper/tools/webscraper.yaml | 34 ++ .../provider/builtin/webscraper/webscraper.py | 23 + .../builtin/webscraper/webscraper.yaml | 11 + .../builtin/wikipedia/_assets/icon.svg | 3 + .../wikipedia/tools/wikipedia_search.py | 37 ++ .../wikipedia/tools/wikipedia_search.yaml | 24 + .../provider/builtin/wikipedia/wikipedia.py | 20 + .../provider/builtin/wikipedia/wikipedia.yaml | 11 + .../builtin/wolframalpha/_assets/icon.svg | 23 + .../wolframalpha/tools/wolframalpha.py | 77 +++ .../wolframalpha/tools/wolframalpha.yaml | 23 + .../builtin/wolframalpha/wolframalpha.py | 24 + .../builtin/wolframalpha/wolframalpha.yaml | 24 + .../provider/builtin/yahoo/_assets/icon.png | Bin 0 -> 7647 bytes .../provider/builtin/yahoo/tools/analytics.py | 69 +++ .../builtin/yahoo/tools/analytics.yaml | 46 ++ .../provider/builtin/yahoo/tools/news.py | 46 ++ .../provider/builtin/yahoo/tools/news.yaml | 24 + .../provider/builtin/yahoo/tools/ticker.py | 25 + .../provider/builtin/yahoo/tools/ticker.yaml | 24 + .../tools/provider/builtin/yahoo/yahoo.py | 20 + .../tools/provider/builtin/yahoo/yahoo.yaml | 11 + .../provider/builtin/youtube/_assets/icon.png | Bin 0 -> 1073 bytes .../provider/builtin/youtube/tools/videos.py | 66 ++ .../builtin/youtube/tools/videos.yaml | 46 ++ .../tools/provider/builtin/youtube/youtube.py | 22 + .../provider/builtin/youtube/youtube.yaml | 24 + .../tools/provider/builtin_tool_provider.py | 286 +++++++++ api/core/tools/provider/tool_provider.py | 218 +++++++ api/core/tools/tool/api_tool.py | 222 +++++++ api/core/tools/tool/builtin_tool.py | 140 +++++ .../dataset_multi_retriever_tool.py | 2 +- .../dataset_retriever_tool.py | 2 +- api/core/tools/tool/dataset_retriever_tool.py | 95 +++ api/core/tools/tool/tool.py | 302 +++++++++ api/core/tools/tool_file_manager.py | 197 ++++++ api/core/tools/tool_manager.py | 448 ++++++++++++++ api/core/tools/utils/configration.py | 77 +++ api/core/tools/utils/encoder.py | 21 + api/core/tools/utils/parser.py | 341 +++++++++++ api/core/tools/utils/web_reader_tool.py | 446 ++++++++++++++ ...aset_join_when_app_model_config_updated.py | 19 +- api/fields/app_fields.py | 6 +- api/fields/conversation_fields.py | 15 + api/fields/installed_app_fields.py | 1 + api/fields/message_fields.py | 43 +- ...ef91f18_rename_api_provider_description.py | 34 ++ .../053da0c1d756_add_api_tool_privacy.py | 51 ++ ...84c228_remove_tool_id_from_model_invoke.py | 32 + ...9d_add_message_files_into_agent_thought.py | 32 + .../3ef9b2b6bee6_add_assistant_app.py | 67 ++ .../versions/4823da1d26cf_add_tool_file.py | 37 ++ ...fee_change_message_chain_id_to_nullable.py | 36 ++ ...daa_add_tool_conversation_variables_idx.py | 34 ++ ...6f3c800_rename_api_provider_credentails.py | 32 + ...fafbd60eca1_add_message_file_belongs_to.py | 32 + .../ad472b61a054_add_api_provider_icon.py | 32 + .../c71211c8f604_add_tool_invoke_model_log.py | 49 ++ .../de95f5c77138_migration_serpapi_api_key.py | 109 ++++ .../f25003750af4_add_created_updated_at.py | 34 ++ api/models/model.py | 94 ++- api/models/tools.py | 227 +++++++ api/requirements.txt | 5 +- api/services/app_model_config_service.py | 53 +- api/services/completion_service.py | 2 + api/services/tools_manage_service.py | 523 ++++++++++++++++ api/tests/integration_tests/.gitignore | 1 + api/tests/integration_tests/tools/__init__.py | 0 .../tools/__mock_server/openapi_todo.py | 38 ++ .../tools/test_all_provider.py | 9 + 175 files changed, 11619 insertions(+), 1235 deletions(-) create mode 100644 .github/workflows/tool-tests.yaml delete mode 100644 api/controllers/console/universal_chat/conversation.py delete mode 100644 api/controllers/console/universal_chat/message.py delete mode 100644 api/controllers/console/universal_chat/parameter.py delete mode 100644 api/controllers/console/universal_chat/wraps.py create mode 100644 api/controllers/files/tool_files.py delete mode 100644 api/core/app_runner/agent_app_runner.py create mode 100644 api/core/app_runner/assistant_app_runner.py create mode 100644 api/core/callback_handler/agent_tool_callback_handler.py create mode 100644 api/core/features/assistant_base_runner.py create mode 100644 api/core/features/assistant_cot_runner.py create mode 100644 api/core/features/assistant_fc_runner.py create mode 100644 api/core/file/tool_file_parser.py create mode 100644 api/core/tools/README.md create mode 100644 api/core/tools/README_CN.md create mode 100644 api/core/tools/docs/en_US/advanced_scale_out.md create mode 100644 api/core/tools/docs/en_US/tool_scale_out.md create mode 100644 api/core/tools/docs/zh_Hans/advanced_scale_out.md create mode 100644 api/core/tools/docs/zh_Hans/images/index/image-1.png create mode 100644 api/core/tools/docs/zh_Hans/images/index/image-2.png create mode 100644 api/core/tools/docs/zh_Hans/images/index/image.png create mode 100644 api/core/tools/docs/zh_Hans/tool_scale_out.md create mode 100644 api/core/tools/entities/common_entities.py create mode 100644 api/core/tools/entities/constant.py create mode 100644 api/core/tools/entities/tool_bundle.py create mode 100644 api/core/tools/entities/tool_entities.py create mode 100644 api/core/tools/entities/user_entities.py create mode 100644 api/core/tools/errors.py create mode 100644 api/core/tools/model/errors.py create mode 100644 api/core/tools/model/tool_model_manager.py create mode 100644 api/core/tools/prompt/template.py create mode 100644 api/core/tools/provider/api_tool_provider.py create mode 100644 api/core/tools/provider/app_tool_provider.py create mode 100644 api/core/tools/provider/builtin/__init__.py create mode 100644 api/core/tools/provider/builtin/_positions.py create mode 100644 api/core/tools/provider/builtin/chart/_assets/icon.png create mode 100644 api/core/tools/provider/builtin/chart/chart.py create mode 100644 api/core/tools/provider/builtin/chart/chart.yaml create mode 100644 api/core/tools/provider/builtin/chart/tools/bar.py create mode 100644 api/core/tools/provider/builtin/chart/tools/bar.yaml create mode 100644 api/core/tools/provider/builtin/chart/tools/line.py create mode 100644 api/core/tools/provider/builtin/chart/tools/line.yaml create mode 100644 api/core/tools/provider/builtin/chart/tools/pie.py create mode 100644 api/core/tools/provider/builtin/chart/tools/pie.yaml create mode 100644 api/core/tools/provider/builtin/dalle/__init__.py create mode 100644 api/core/tools/provider/builtin/dalle/_assets/icon.png create mode 100644 api/core/tools/provider/builtin/dalle/dalle.py create mode 100644 api/core/tools/provider/builtin/dalle/dalle.yaml create mode 100644 api/core/tools/provider/builtin/dalle/tools/dalle2.py create mode 100644 api/core/tools/provider/builtin/dalle/tools/dalle2.yaml create mode 100644 api/core/tools/provider/builtin/dalle/tools/dalle3.py create mode 100644 api/core/tools/provider/builtin/dalle/tools/dalle3.yaml create mode 100644 api/core/tools/provider/builtin/google/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/google/google.py create mode 100644 api/core/tools/provider/builtin/google/google.yaml create mode 100644 api/core/tools/provider/builtin/google/tools/google_search.py create mode 100644 api/core/tools/provider/builtin/google/tools/google_search.yaml create mode 100644 api/core/tools/provider/builtin/stablediffusion/_assets/icon.png create mode 100644 api/core/tools/provider/builtin/stablediffusion/stablediffusion.py create mode 100644 api/core/tools/provider/builtin/stablediffusion/stablediffusion.yaml create mode 100644 api/core/tools/provider/builtin/stablediffusion/tools/stable_diffusion.py create mode 100644 api/core/tools/provider/builtin/stablediffusion/tools/stable_diffusion.yaml create mode 100644 api/core/tools/provider/builtin/time/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/time/time.py create mode 100644 api/core/tools/provider/builtin/time/time.yaml create mode 100644 api/core/tools/provider/builtin/time/tools/current_time.py create mode 100644 api/core/tools/provider/builtin/time/tools/current_time.yaml create mode 100644 api/core/tools/provider/builtin/vectorizer/_assets/icon.png create mode 100644 api/core/tools/provider/builtin/vectorizer/tools/test_data.py create mode 100644 api/core/tools/provider/builtin/vectorizer/tools/vectorizer.py create mode 100644 api/core/tools/provider/builtin/vectorizer/tools/vectorizer.yaml create mode 100644 api/core/tools/provider/builtin/vectorizer/vectorizer.py create mode 100644 api/core/tools/provider/builtin/vectorizer/vectorizer.yaml create mode 100644 api/core/tools/provider/builtin/webscraper/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/webscraper/tools/webscraper.py create mode 100644 api/core/tools/provider/builtin/webscraper/tools/webscraper.yaml create mode 100644 api/core/tools/provider/builtin/webscraper/webscraper.py create mode 100644 api/core/tools/provider/builtin/webscraper/webscraper.yaml create mode 100644 api/core/tools/provider/builtin/wikipedia/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/wikipedia/tools/wikipedia_search.py create mode 100644 api/core/tools/provider/builtin/wikipedia/tools/wikipedia_search.yaml create mode 100644 api/core/tools/provider/builtin/wikipedia/wikipedia.py create mode 100644 api/core/tools/provider/builtin/wikipedia/wikipedia.yaml create mode 100644 api/core/tools/provider/builtin/wolframalpha/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/wolframalpha/tools/wolframalpha.py create mode 100644 api/core/tools/provider/builtin/wolframalpha/tools/wolframalpha.yaml create mode 100644 api/core/tools/provider/builtin/wolframalpha/wolframalpha.py create mode 100644 api/core/tools/provider/builtin/wolframalpha/wolframalpha.yaml create mode 100644 api/core/tools/provider/builtin/yahoo/_assets/icon.png create mode 100644 api/core/tools/provider/builtin/yahoo/tools/analytics.py create mode 100644 api/core/tools/provider/builtin/yahoo/tools/analytics.yaml create mode 100644 api/core/tools/provider/builtin/yahoo/tools/news.py create mode 100644 api/core/tools/provider/builtin/yahoo/tools/news.yaml create mode 100644 api/core/tools/provider/builtin/yahoo/tools/ticker.py create mode 100644 api/core/tools/provider/builtin/yahoo/tools/ticker.yaml create mode 100644 api/core/tools/provider/builtin/yahoo/yahoo.py create mode 100644 api/core/tools/provider/builtin/yahoo/yahoo.yaml create mode 100644 api/core/tools/provider/builtin/youtube/_assets/icon.png create mode 100644 api/core/tools/provider/builtin/youtube/tools/videos.py create mode 100644 api/core/tools/provider/builtin/youtube/tools/videos.yaml create mode 100644 api/core/tools/provider/builtin/youtube/youtube.py create mode 100644 api/core/tools/provider/builtin/youtube/youtube.yaml create mode 100644 api/core/tools/provider/builtin_tool_provider.py create mode 100644 api/core/tools/provider/tool_provider.py create mode 100644 api/core/tools/tool/api_tool.py create mode 100644 api/core/tools/tool/builtin_tool.py rename api/core/{tool => tools/tool/dataset_retriever}/dataset_multi_retriever_tool.py (99%) rename api/core/{tool => tools/tool/dataset_retriever}/dataset_retriever_tool.py (99%) create mode 100644 api/core/tools/tool/dataset_retriever_tool.py create mode 100644 api/core/tools/tool/tool.py create mode 100644 api/core/tools/tool_file_manager.py create mode 100644 api/core/tools/tool_manager.py create mode 100644 api/core/tools/utils/configration.py create mode 100644 api/core/tools/utils/encoder.py create mode 100644 api/core/tools/utils/parser.py create mode 100644 api/core/tools/utils/web_reader_tool.py create mode 100644 api/migrations/versions/00bacef91f18_rename_api_provider_description.py create mode 100644 api/migrations/versions/053da0c1d756_add_api_tool_privacy.py create mode 100644 api/migrations/versions/114eed84c228_remove_tool_id_from_model_invoke.py create mode 100644 api/migrations/versions/23db93619b9d_add_message_files_into_agent_thought.py create mode 100644 api/migrations/versions/3ef9b2b6bee6_add_assistant_app.py create mode 100644 api/migrations/versions/4823da1d26cf_add_tool_file.py create mode 100644 api/migrations/versions/4829e54d2fee_change_message_chain_id_to_nullable.py create mode 100644 api/migrations/versions/8ae9bc661daa_add_tool_conversation_variables_idx.py create mode 100644 api/migrations/versions/8ec536f3c800_rename_api_provider_credentails.py create mode 100644 api/migrations/versions/9fafbd60eca1_add_message_file_belongs_to.py create mode 100644 api/migrations/versions/ad472b61a054_add_api_provider_icon.py create mode 100644 api/migrations/versions/c71211c8f604_add_tool_invoke_model_log.py create mode 100644 api/migrations/versions/de95f5c77138_migration_serpapi_api_key.py create mode 100644 api/migrations/versions/f25003750af4_add_created_updated_at.py create mode 100644 api/models/tools.py create mode 100644 api/services/tools_manage_service.py create mode 100644 api/tests/integration_tests/.gitignore create mode 100644 api/tests/integration_tests/tools/__init__.py create mode 100644 api/tests/integration_tests/tools/__mock_server/openapi_todo.py create mode 100644 api/tests/integration_tests/tools/test_all_provider.py diff --git a/.github/workflows/tool-tests.yaml b/.github/workflows/tool-tests.yaml new file mode 100644 index 000000000..3ea7c2492 --- /dev/null +++ b/.github/workflows/tool-tests.yaml @@ -0,0 +1,26 @@ +name: Run Tool Pytest + +on: + pull_request: + branches: + - main + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + cache: 'pip' + cache-dependency-path: ./api/requirements.txt + + - name: Install dependencies + run: pip install -r ./api/requirements.txt + + - name: Run pytest + run: pytest ./api/tests/integration_tests/tools/test_all_provider.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c4376631b..e1c087a6c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,6 +91,8 @@ To validate your set up, head over to [http://localhost:3000](http://localhost:3 If you are adding a model provider, [this guide](https://github.com/langgenius/dify/blob/main/api/core/model_runtime/README.md) is for you. +If you are adding a tool provider to Agent or Workflow, [this guide](./api/core/tools/README.md) is for you. + To help you quickly navigate where your contribution fits, a brief, annotated outline of Dify's backend & frontend is as follows: ### Backend diff --git a/api/app.py b/api/app.py index b7234b6a1..e46cb84bb 100644 --- a/api/app.py +++ b/api/app.py @@ -30,7 +30,7 @@ from flask import Flask, Response, request from flask_cors import CORS from libs.passport import PassportService # DO NOT REMOVE BELOW -from models import account, dataset, model, source, task, tool, web +from models import account, dataset, model, source, task, tool, web, tools from services.account_service import AccountService # DO NOT REMOVE ABOVE diff --git a/api/commands.py b/api/commands.py index a9a04c9f1..1a2af23da 100644 --- a/api/commands.py +++ b/api/commands.py @@ -22,7 +22,7 @@ from libs.password import hash_password, password_pattern, valid_password from libs.rsa import generate_key_pair from models.account import InvitationCode, Tenant, TenantAccountJoin from models.dataset import Dataset, DatasetCollectionBinding, DatasetQuery, Document -from models.model import Account, App, AppModelConfig, Message, MessageAnnotation +from models.model import Account, App, AppModelConfig, Message, MessageAnnotation, InstalledApp from models.provider import Provider, ProviderModel, ProviderQuotaType, ProviderType from qdrant_client.http.models import TextIndexParams, TextIndexType, TokenizerType from tqdm import tqdm @@ -775,6 +775,66 @@ def add_annotation_question_field_value(): click.echo( click.style(f'Congratulations! add annotation question value successful. Deal count {message_annotation_deal_count}', fg='green')) +@click.command('migrate-universal-chat-to-installed-app', help='Migrate universal chat to installed app.') +@click.option("--batch-size", default=500, help="Number of records to migrate in each batch.") +def migrate_universal_chat_to_installed_app(batch_size): + total_records = db.session.query(App).filter( + App.is_universal == True + ).count() + if total_records == 0: + click.secho("No data to migrate.", fg='green') + return + + num_batches = (total_records + batch_size - 1) // batch_size + + with tqdm(total=total_records, desc="Migrating Data") as pbar: + for i in range(num_batches): + offset = i * batch_size + limit = min(batch_size, total_records - offset) + + click.secho(f"Fetching batch {i + 1}/{num_batches} from source database...", fg='green') + + data_batch: list[App] = db.session.query(App) \ + .filter(App.is_universal == True) \ + .order_by(App.created_at) \ + .offset(offset).limit(limit).all() + + if not data_batch: + click.secho("No more data to migrate.", fg='green') + break + + try: + click.secho(f"Migrating {len(data_batch)} records...", fg='green') + for data in data_batch: + # check if the app is already installed + installed_app = db.session.query(InstalledApp).filter( + InstalledApp.app_id == data.id + ).first() + + if installed_app: + continue + + # insert installed app + installed_app = InstalledApp( + app_id=data.id, + tenant_id=data.tenant_id, + position=0, + app_owner_tenant_id=data.tenant_id, + is_pinned=True, + last_used_at=datetime.datetime.utcnow(), + ) + + db.session.add(installed_app) + + db.session.commit() + + except Exception as e: + click.secho(f"Error while migrating data: {e}, app_id: {data.id}", fg='red') + continue + + click.secho(f"Successfully migrated batch {i + 1}/{num_batches}.", fg='green') + + pbar.update(len(data_batch)) def register_commands(app): app.cli.add_command(reset_password) @@ -791,3 +851,4 @@ def register_commands(app): app.cli.add_command(migrate_default_input_to_dataset_query_variable) app.cli.add_command(add_qdrant_full_text_index) app.cli.add_command(add_annotation_question_field_value) + app.cli.add_command(migrate_universal_chat_to_installed_app) diff --git a/api/controllers/console/__init__.py b/api/controllers/console/__init__.py index 1394452c8..651d45737 100644 --- a/api/controllers/console/__init__.py +++ b/api/controllers/console/__init__.py @@ -16,7 +16,5 @@ from .billing import billing from .datasets import data_source, datasets, datasets_document, datasets_segments, file, hit_testing # Import explore controllers from .explore import audio, completion, conversation, installed_app, message, parameter, recommended_app, saved_message -# Import universal chat controllers -from .universal_chat import audio, chat, conversation, message, parameter # Import workspace controllers from .workspace import account, members, model_providers, models, tool_providers, workspace diff --git a/api/controllers/console/app/app.py b/api/controllers/console/app/app.py index 6ae0ef480..fe3f145df 100644 --- a/api/controllers/console/app/app.py +++ b/api/controllers/console/app/app.py @@ -16,14 +16,15 @@ from events.app_event import app_was_created, app_was_deleted from extensions.ext_database import db from fields.app_fields import (app_detail_fields, app_detail_fields_with_site, app_pagination_fields, template_list_fields) +from flask import current_app from flask_login import current_user from flask_restful import Resource, abort, inputs, marshal_with, reqparse from libs.login import login_required from models.model import App, AppModelConfig, Site +from models.tools import ApiToolProvider from services.app_model_config_service import AppModelConfigService from werkzeug.exceptions import Forbidden - def _get_app(app_id, tenant_id): app = db.session.query(App).filter(App.id == app_id, App.tenant_id == tenant_id).first() if not app: @@ -42,14 +43,30 @@ class AppListApi(Resource): parser = reqparse.RequestParser() parser.add_argument('page', type=inputs.int_range(1, 99999), required=False, default=1, location='args') parser.add_argument('limit', type=inputs.int_range(1, 100), required=False, default=20, location='args') + parser.add_argument('mode', type=str, choices=['chat', 'completion', 'all'], default='all', location='args', required=False) + parser.add_argument('name', type=str, location='args', required=False) args = parser.parse_args() + filters = [ + App.tenant_id == current_user.current_tenant_id, + ] + + if args['mode'] == 'completion': + filters.append(App.mode == 'completion') + elif args['mode'] == 'chat': + filters.append(App.mode == 'chat') + else: + pass + + if 'name' in args and args['name']: + filters.append(App.name.ilike(f'%{args["name"]}%')) + app_models = db.paginate( - db.select(App).where(App.tenant_id == current_user.current_tenant_id, - App.is_universal == False).order_by(App.created_at.desc()), + db.select(App).where(*filters).order_by(App.created_at.desc()), page=args['page'], per_page=args['limit'], - error_out=False) + error_out=False + ) return app_models @@ -62,7 +79,7 @@ class AppListApi(Resource): """Create app""" parser = reqparse.RequestParser() parser.add_argument('name', type=str, required=True, location='json') - parser.add_argument('mode', type=str, choices=['completion', 'chat'], location='json') + parser.add_argument('mode', type=str, choices=['completion', 'chat', 'assistant'], location='json') parser.add_argument('icon', type=str, location='json') parser.add_argument('icon_background', type=str, location='json') parser.add_argument('model_config', type=dict, location='json') @@ -178,7 +195,7 @@ class AppListApi(Resource): app_was_created.send(app) return app, 201 - + class AppTemplateApi(Resource): diff --git a/api/controllers/console/explore/installed_app.py b/api/controllers/console/explore/installed_app.py index 7bde88efb..44c54427a 100644 --- a/api/controllers/console/explore/installed_app.py +++ b/api/controllers/console/explore/installed_app.py @@ -33,8 +33,9 @@ class InstalledAppsListApi(Resource): 'app_owner_tenant_id': installed_app.app_owner_tenant_id, 'is_pinned': installed_app.is_pinned, 'last_used_at': installed_app.last_used_at, - "editable": current_user.role in ["owner", "admin"], - "uninstallable": current_tenant_id == installed_app.app_owner_tenant_id + 'editable': current_user.role in ["owner", "admin"], + 'uninstallable': current_tenant_id == installed_app.app_owner_tenant_id, + 'is_agent': installed_app.is_agent } for installed_app in installed_apps ] diff --git a/api/controllers/console/explore/message.py b/api/controllers/console/explore/message.py index 05c5619ce..404b855bb 100644 --- a/api/controllers/console/explore/message.py +++ b/api/controllers/console/explore/message.py @@ -17,9 +17,9 @@ from core.model_runtime.errors.invoke import InvokeError from fields.message_fields import message_infinite_scroll_pagination_fields from flask import Response, stream_with_context from flask_login import current_user -from flask_restful import marshal_with, reqparse +from flask_restful import marshal_with, reqparse, fields from flask_restful.inputs import int_range -from libs.helper import uuid_value +from libs.helper import uuid_value, TimestampField from services.completion_service import CompletionService from services.errors.app import MoreLikeThisDisabledError from services.errors.conversation import ConversationNotExistsError @@ -29,7 +29,6 @@ from werkzeug.exceptions import InternalServerError, NotFound class MessageListApi(InstalledAppResource): - @marshal_with(message_infinite_scroll_pagination_fields) def get(self, installed_app): app_model = installed_app.app @@ -51,7 +50,6 @@ class MessageListApi(InstalledAppResource): except services.errors.message.FirstMessageNotExistsError: raise NotFound("First Message Not Exists.") - class MessageFeedbackApi(InstalledAppResource): def post(self, installed_app, message_id): app_model = installed_app.app diff --git a/api/controllers/console/explore/parameter.py b/api/controllers/console/explore/parameter.py index 7be696612..0a76f9d58 100644 --- a/api/controllers/console/explore/parameter.py +++ b/api/controllers/console/explore/parameter.py @@ -1,10 +1,14 @@ # -*- coding:utf-8 -*- +import json + from controllers.console import api from controllers.console.explore.wraps import InstalledAppResource from flask import current_app from flask_restful import fields, marshal_with -from models.model import InstalledApp +from models.model import InstalledApp, AppModelConfig +from models.tools import ApiToolProvider +from extensions.ext_database import db class AppParameterApi(InstalledAppResource): """Resource for app variables.""" @@ -58,5 +62,42 @@ class AppParameterApi(InstalledAppResource): } } +class ExploreAppMetaApi(InstalledAppResource): + def get(self, installed_app: InstalledApp): + """Get app meta""" + app_model_config: AppModelConfig = installed_app.app.app_model_config + + agent_config = app_model_config.agent_mode_dict or {} + meta = { + 'tool_icons': {} + } + + # get all tools + tools = agent_config.get('tools', []) + url_prefix = (current_app.config.get("CONSOLE_API_URL") + + f"/console/api/workspaces/current/tool-provider/builtin/") + for tool in tools: + keys = list(tool.keys()) + if len(keys) >= 4: + # current tool standard + provider_type = tool.get('provider_type') + provider_id = tool.get('provider_id') + tool_name = tool.get('tool_name') + if provider_type == 'builtin': + meta['tool_icons'][tool_name] = url_prefix + provider_id + '/icon' + elif provider_type == 'api': + try: + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.id == provider_id + ) + meta['tool_icons'][tool_name] = json.loads(provider.icon) + except: + meta['tool_icons'][tool_name] = { + "background": "#252525", + "content": "\ud83d\ude01" + } + + return meta api.add_resource(AppParameterApi, '/installed-apps//parameters', endpoint='installed_app_parameters') +api.add_resource(ExploreAppMetaApi, '/installed-apps//meta', endpoint='installed_app_meta') diff --git a/api/controllers/console/explore/recommended_app.py b/api/controllers/console/explore/recommended_app.py index 71d77ee74..92e64996b 100644 --- a/api/controllers/console/explore/recommended_app.py +++ b/api/controllers/console/explore/recommended_app.py @@ -29,7 +29,8 @@ recommended_app_fields = { 'is_listed': fields.Boolean, 'install_count': fields.Integer, 'installed': fields.Boolean, - 'editable': fields.Boolean + 'editable': fields.Boolean, + 'is_agent': fields.Boolean } recommended_app_list_fields = { @@ -82,6 +83,7 @@ class RecommendedAppListApi(Resource): 'install_count': recommended_app.install_count, 'installed': installed, 'editable': current_user.role in ['owner', 'admin'], + "is_agent": app.is_agent } recommended_apps_result.append(recommended_app_result) diff --git a/api/controllers/console/universal_chat/audio.py b/api/controllers/console/universal_chat/audio.py index 2566448d4..0ef1e4ece 100644 --- a/api/controllers/console/universal_chat/audio.py +++ b/api/controllers/console/universal_chat/audio.py @@ -60,5 +60,3 @@ class UniversalChatAudioApi(UniversalChatResource): logging.exception("internal server error.") raise InternalServerError() - -api.add_resource(UniversalChatAudioApi, '/universal-chat/audio-to-text') \ No newline at end of file diff --git a/api/controllers/console/universal_chat/chat.py b/api/controllers/console/universal_chat/chat.py index e0adc05c3..e69de29bb 100644 --- a/api/controllers/console/universal_chat/chat.py +++ b/api/controllers/console/universal_chat/chat.py @@ -1,120 +0,0 @@ -import json -import logging -from typing import Generator, Union - -import services -from controllers.console import api -from controllers.console.app.error import (AppUnavailableError, CompletionRequestError, ConversationCompletedError, - ProviderModelCurrentlyNotSupportError, ProviderNotInitializeError, - ProviderQuotaExceededError) -from controllers.console.universal_chat.wraps import UniversalChatResource -from core.application_queue_manager import ApplicationQueueManager -from core.entities.application_entities import InvokeFrom -from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError -from core.model_runtime.errors.invoke import InvokeError -from flask import Response, stream_with_context -from flask_login import current_user -from flask_restful import reqparse -from libs.helper import uuid_value -from services.completion_service import CompletionService -from werkzeug.exceptions import InternalServerError, NotFound - - -class UniversalChatApi(UniversalChatResource): - def post(self, universal_app): - app_model = universal_app - - parser = reqparse.RequestParser() - parser.add_argument('query', type=str, required=True, location='json') - parser.add_argument('files', type=list, required=False, location='json') - parser.add_argument('conversation_id', type=uuid_value, location='json') - parser.add_argument('provider', type=str, required=True, location='json') - parser.add_argument('model', type=str, required=True, location='json') - parser.add_argument('tools', type=list, required=True, location='json') - parser.add_argument('retriever_from', type=str, required=False, default='universal_app', location='json') - args = parser.parse_args() - - app_model_config = app_model.app_model_config - - # update app model config - args['model_config'] = app_model_config.to_dict() - args['model_config']['model']['name'] = args['model'] - args['model_config']['model']['provider'] = args['provider'] - args['model_config']['agent_mode']['tools'] = args['tools'] - - if not args['model_config']['agent_mode']['tools']: - args['model_config']['agent_mode']['tools'] = [ - { - "current_datetime": { - "enabled": True - } - } - ] - else: - args['model_config']['agent_mode']['tools'].append({ - "current_datetime": { - "enabled": True - } - }) - - args['inputs'] = {} - - del args['model'] - del args['tools'] - - args['auto_generate_name'] = False - - try: - response = CompletionService.completion( - app_model=app_model, - user=current_user, - args=args, - invoke_from=InvokeFrom.EXPLORE, - streaming=True, - is_model_config_override=True, - ) - - return compact_response(response) - except services.errors.conversation.ConversationNotExistsError: - raise NotFound("Conversation Not Exists.") - except services.errors.conversation.ConversationCompletedError: - raise ConversationCompletedError() - except services.errors.app_model_config.AppModelConfigBrokenError: - logging.exception("App model config broken.") - raise AppUnavailableError() - except ProviderTokenNotInitError: - raise ProviderNotInitializeError() - except QuotaExceededError: - raise ProviderQuotaExceededError() - except ModelCurrentlyNotSupportError: - raise ProviderModelCurrentlyNotSupportError() - except InvokeError as e: - raise CompletionRequestError(e.description) - except ValueError as e: - raise e - except Exception as e: - logging.exception("internal server error.") - raise InternalServerError() - - -class UniversalChatStopApi(UniversalChatResource): - def post(self, universal_app, task_id): - ApplicationQueueManager.set_stop_flag(task_id, InvokeFrom.EXPLORE, current_user.id) - - return {'result': 'success'}, 200 - - -def compact_response(response: Union[dict, Generator]) -> Response: - if isinstance(response, dict): - return Response(response=json.dumps(response), status=200, mimetype='application/json') - else: - def generate() -> Generator: - for chunk in response: - yield chunk - - return Response(stream_with_context(generate()), status=200, - mimetype='text/event-stream') - - -api.add_resource(UniversalChatApi, '/universal-chat/messages') -api.add_resource(UniversalChatStopApi, '/universal-chat/messages//stop') diff --git a/api/controllers/console/universal_chat/conversation.py b/api/controllers/console/universal_chat/conversation.py deleted file mode 100644 index af141b67a..000000000 --- a/api/controllers/console/universal_chat/conversation.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*- coding:utf-8 -*- -from controllers.console import api -from controllers.console.universal_chat.wraps import UniversalChatResource -from fields.conversation_fields import (conversation_with_model_config_fields, - conversation_with_model_config_infinite_scroll_pagination_fields) -from flask_login import current_user -from flask_restful import fields, marshal_with, reqparse -from flask_restful.inputs import int_range -from libs.helper import TimestampField, uuid_value -from services.conversation_service import ConversationService -from services.errors.conversation import ConversationNotExistsError, LastConversationNotExistsError -from services.web_conversation_service import WebConversationService -from werkzeug.exceptions import NotFound - - -class UniversalChatConversationListApi(UniversalChatResource): - - @marshal_with(conversation_with_model_config_infinite_scroll_pagination_fields) - def get(self, universal_app): - app_model = universal_app - - parser = reqparse.RequestParser() - parser.add_argument('last_id', type=uuid_value, location='args') - parser.add_argument('limit', type=int_range(1, 100), required=False, default=20, location='args') - parser.add_argument('pinned', type=str, choices=['true', 'false', None], location='args') - args = parser.parse_args() - - pinned = None - if 'pinned' in args and args['pinned'] is not None: - pinned = True if args['pinned'] == 'true' else False - - try: - return WebConversationService.pagination_by_last_id( - app_model=app_model, - user=current_user, - last_id=args['last_id'], - limit=args['limit'], - pinned=pinned - ) - except LastConversationNotExistsError: - raise NotFound("Last Conversation Not Exists.") - - -class UniversalChatConversationApi(UniversalChatResource): - def delete(self, universal_app, c_id): - app_model = universal_app - conversation_id = str(c_id) - - try: - ConversationService.delete(app_model, conversation_id, current_user) - except ConversationNotExistsError: - raise NotFound("Conversation Not Exists.") - - WebConversationService.unpin(app_model, conversation_id, current_user) - - return {"result": "success"}, 204 - - -class UniversalChatConversationRenameApi(UniversalChatResource): - - @marshal_with(conversation_with_model_config_fields) - def post(self, universal_app, c_id): - app_model = universal_app - conversation_id = str(c_id) - - parser = reqparse.RequestParser() - parser.add_argument('name', type=str, required=False, location='json') - parser.add_argument('auto_generate', type=bool, required=False, default=False, location='json') - args = parser.parse_args() - - try: - return ConversationService.rename( - app_model, - conversation_id, - current_user, - args['name'], - args['auto_generate'] - ) - except ConversationNotExistsError: - raise NotFound("Conversation Not Exists.") - - -class UniversalChatConversationPinApi(UniversalChatResource): - - def patch(self, universal_app, c_id): - app_model = universal_app - conversation_id = str(c_id) - - try: - WebConversationService.pin(app_model, conversation_id, current_user) - except ConversationNotExistsError: - raise NotFound("Conversation Not Exists.") - - return {"result": "success"} - - -class UniversalChatConversationUnPinApi(UniversalChatResource): - def patch(self, universal_app, c_id): - app_model = universal_app - conversation_id = str(c_id) - WebConversationService.unpin(app_model, conversation_id, current_user) - - return {"result": "success"} - - -api.add_resource(UniversalChatConversationRenameApi, '/universal-chat/conversations//name') -api.add_resource(UniversalChatConversationListApi, '/universal-chat/conversations') -api.add_resource(UniversalChatConversationApi, '/universal-chat/conversations/') -api.add_resource(UniversalChatConversationPinApi, '/universal-chat/conversations//pin') -api.add_resource(UniversalChatConversationUnPinApi, '/universal-chat/conversations//unpin') diff --git a/api/controllers/console/universal_chat/message.py b/api/controllers/console/universal_chat/message.py deleted file mode 100644 index 503615d75..000000000 --- a/api/controllers/console/universal_chat/message.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding:utf-8 -*- -import logging - -import services -from controllers.console import api -from controllers.console.app.error import (CompletionRequestError, ProviderModelCurrentlyNotSupportError, - ProviderNotInitializeError, ProviderQuotaExceededError) -from controllers.console.explore.error import AppSuggestedQuestionsAfterAnswerDisabledError -from controllers.console.universal_chat.wraps import UniversalChatResource -from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError -from core.model_runtime.errors.invoke import InvokeError -from flask_login import current_user -from flask_restful import fields, marshal_with, reqparse -from flask_restful.inputs import int_range -from libs.helper import TimestampField, uuid_value -from services.errors.conversation import ConversationNotExistsError -from services.errors.message import MessageNotExistsError, SuggestedQuestionsAfterAnswerDisabledError -from services.message_service import MessageService -from werkzeug.exceptions import InternalServerError, NotFound - - -class UniversalChatMessageListApi(UniversalChatResource): - feedback_fields = { - 'rating': fields.String - } - - agent_thought_fields = { - 'id': fields.String, - 'chain_id': fields.String, - 'message_id': fields.String, - 'position': fields.Integer, - 'thought': fields.String, - 'tool': fields.String, - 'tool_input': fields.String, - 'created_at': TimestampField - } - - retriever_resource_fields = { - 'id': fields.String, - 'message_id': fields.String, - 'position': fields.Integer, - 'dataset_id': fields.String, - 'dataset_name': fields.String, - 'document_id': fields.String, - 'document_name': fields.String, - 'data_source_type': fields.String, - 'segment_id': fields.String, - 'score': fields.Float, - 'hit_count': fields.Integer, - 'word_count': fields.Integer, - 'segment_position': fields.Integer, - 'index_node_hash': fields.String, - 'content': fields.String, - 'created_at': TimestampField - } - - message_fields = { - 'id': fields.String, - 'conversation_id': fields.String, - 'inputs': fields.Raw, - 'query': fields.String, - 'answer': fields.String, - 'feedback': fields.Nested(feedback_fields, attribute='user_feedback', allow_null=True), - 'retriever_resources': fields.List(fields.Nested(retriever_resource_fields)), - 'created_at': TimestampField, - 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)) - } - - message_infinite_scroll_pagination_fields = { - 'limit': fields.Integer, - 'has_more': fields.Boolean, - 'data': fields.List(fields.Nested(message_fields)) - } - - @marshal_with(message_infinite_scroll_pagination_fields) - def get(self, universal_app): - app_model = universal_app - - parser = reqparse.RequestParser() - parser.add_argument('conversation_id', required=True, type=uuid_value, location='args') - parser.add_argument('first_id', type=uuid_value, location='args') - parser.add_argument('limit', type=int_range(1, 100), required=False, default=20, location='args') - args = parser.parse_args() - - try: - return MessageService.pagination_by_first_id(app_model, current_user, - args['conversation_id'], args['first_id'], args['limit']) - except services.errors.conversation.ConversationNotExistsError: - raise NotFound("Conversation Not Exists.") - except services.errors.message.FirstMessageNotExistsError: - raise NotFound("First Message Not Exists.") - - -class UniversalChatMessageFeedbackApi(UniversalChatResource): - def post(self, universal_app, message_id): - app_model = universal_app - message_id = str(message_id) - - parser = reqparse.RequestParser() - parser.add_argument('rating', type=str, choices=['like', 'dislike', None], location='json') - args = parser.parse_args() - - try: - MessageService.create_feedback(app_model, message_id, current_user, args['rating']) - except services.errors.message.MessageNotExistsError: - raise NotFound("Message Not Exists.") - - return {'result': 'success'} - - -class UniversalChatMessageSuggestedQuestionApi(UniversalChatResource): - def get(self, universal_app, message_id): - app_model = universal_app - message_id = str(message_id) - - try: - questions = MessageService.get_suggested_questions_after_answer( - app_model=app_model, - user=current_user, - message_id=message_id - ) - except MessageNotExistsError: - raise NotFound("Message not found") - except ConversationNotExistsError: - raise NotFound("Conversation not found") - except SuggestedQuestionsAfterAnswerDisabledError: - raise AppSuggestedQuestionsAfterAnswerDisabledError() - except ProviderTokenNotInitError: - raise ProviderNotInitializeError() - except QuotaExceededError: - raise ProviderQuotaExceededError() - except ModelCurrentlyNotSupportError: - raise ProviderModelCurrentlyNotSupportError() - except InvokeError as e: - raise CompletionRequestError(e.description) - except Exception: - logging.exception("internal server error.") - raise InternalServerError() - - return {'data': questions} - - -api.add_resource(UniversalChatMessageListApi, '/universal-chat/messages') -api.add_resource(UniversalChatMessageFeedbackApi, '/universal-chat/messages//feedbacks') -api.add_resource(UniversalChatMessageSuggestedQuestionApi, '/universal-chat/messages//suggested-questions') diff --git a/api/controllers/console/universal_chat/parameter.py b/api/controllers/console/universal_chat/parameter.py deleted file mode 100644 index dca86e39c..000000000 --- a/api/controllers/console/universal_chat/parameter.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding:utf-8 -*- -import json - -from controllers.console import api -from controllers.console.universal_chat.wraps import UniversalChatResource -from flask_restful import fields, marshal_with -from models.model import App - - -class UniversalChatParameterApi(UniversalChatResource): - """Resource for app variables.""" - parameters_fields = { - 'opening_statement': fields.String, - 'suggested_questions': fields.Raw, - 'suggested_questions_after_answer': fields.Raw, - 'speech_to_text': fields.Raw, - 'retriever_resource': fields.Raw, - 'annotation_reply': fields.Raw - } - - @marshal_with(parameters_fields) - def get(self, universal_app: App): - """Retrieve app parameters.""" - app_model = universal_app - app_model_config = app_model.app_model_config - app_model_config.retriever_resource = json.dumps({'enabled': True}) - - return { - 'opening_statement': app_model_config.opening_statement, - 'suggested_questions': app_model_config.suggested_questions_list, - 'suggested_questions_after_answer': app_model_config.suggested_questions_after_answer_dict, - 'speech_to_text': app_model_config.speech_to_text_dict, - 'retriever_resource': app_model_config.retriever_resource_dict, - 'annotation_reply': app_model_config.annotation_reply_dict, - } - - -api.add_resource(UniversalChatParameterApi, '/universal-chat/parameters') diff --git a/api/controllers/console/universal_chat/wraps.py b/api/controllers/console/universal_chat/wraps.py deleted file mode 100644 index 3e5600639..000000000 --- a/api/controllers/console/universal_chat/wraps.py +++ /dev/null @@ -1,86 +0,0 @@ -import json -from functools import wraps - -from controllers.console.setup import setup_required -from controllers.console.wraps import account_initialization_required -from extensions.ext_database import db -from flask_login import current_user -from flask_restful import Resource -from libs.login import login_required -from models.model import App, AppModelConfig - - -def universal_chat_app_required(view=None): - def decorator(view): - @wraps(view) - def decorated(*args, **kwargs): - # get universal chat app - universal_app = db.session.query(App).filter( - App.tenant_id == current_user.current_tenant_id, - App.is_universal == True - ).first() - - if universal_app is None: - # create universal app if not exists - universal_app = App( - tenant_id=current_user.current_tenant_id, - name='Universal Chat', - mode='chat', - is_universal=True, - icon='', - icon_background='', - api_rpm=0, - api_rph=0, - enable_site=False, - enable_api=False, - status='normal' - ) - - db.session.add(universal_app) - db.session.flush() - - app_model_config = AppModelConfig( - provider="", - model_id="", - configs={}, - opening_statement='', - suggested_questions=json.dumps([]), - suggested_questions_after_answer=json.dumps({'enabled': True}), - speech_to_text=json.dumps({'enabled': True}), - retriever_resource=json.dumps({'enabled': True}), - more_like_this=None, - sensitive_word_avoidance=None, - model=json.dumps({ - "provider": "openai", - "name": "gpt-3.5-turbo-16k", - "completion_params": { - "max_tokens": 800, - "temperature": 0.8, - "top_p": 1, - "presence_penalty": 0, - "frequency_penalty": 0 - } - }), - user_input_form=json.dumps([]), - pre_prompt='', - agent_mode=json.dumps({"enabled": True, "strategy": "function_call", "tools": []}), - ) - - app_model_config.app_id = universal_app.id - db.session.add(app_model_config) - db.session.flush() - - universal_app.app_model_config_id = app_model_config.id - db.session.commit() - - return view(universal_app, *args, **kwargs) - return decorated - - if view: - return decorator(view) - return decorator - - -class UniversalChatResource(Resource): - # must be reversed if there are multiple decorators - method_decorators = [universal_chat_app_required, account_initialization_required, login_required, setup_required] diff --git a/api/controllers/console/workspace/tool_providers.py b/api/controllers/console/workspace/tool_providers.py index c6416e1d3..b694e0bef 100644 --- a/api/controllers/console/workspace/tool_providers.py +++ b/api/controllers/console/workspace/tool_providers.py @@ -1,136 +1,293 @@ import json +from libs.login import login_required +from flask_login import current_user +from flask_restful import Resource, reqparse +from flask import send_file +from werkzeug.exceptions import Forbidden + from controllers.console import api from controllers.console.setup import setup_required from controllers.console.wraps import account_initialization_required -from core.tool.provider.errors import ToolValidateFailedError -from core.tool.provider.tool_provider_service import ToolProviderService -from extensions.ext_database import db -from flask_login import current_user -from flask_restful import Resource, abort, reqparse -from libs.login import login_required -from models.tool import ToolProvider, ToolProviderName -from werkzeug.exceptions import Forbidden +from services.tools_manage_service import ToolManageService + +import io class ToolProviderListApi(Resource): - @setup_required @login_required @account_initialization_required def get(self): + user_id = current_user.id tenant_id = current_user.current_tenant_id - tool_credential_dict = {} - for tool_name in ToolProviderName: - tool_credential_dict[tool_name.value] = { - 'tool_name': tool_name.value, - 'is_enabled': False, - 'credentials': None - } + return ToolManageService.list_tool_providers(user_id, tenant_id) - tool_providers = db.session.query(ToolProvider).filter(ToolProvider.tenant_id == tenant_id).all() +class ToolBuiltinProviderListToolsApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self, provider): + user_id = current_user.id + tenant_id = current_user.current_tenant_id - for p in tool_providers: - if p.is_enabled: - tool_credential_dict[p.tool_name] = { - 'tool_name': p.tool_name, - 'is_enabled': p.is_enabled, - 'credentials': ToolProviderService(tenant_id, p.tool_name).get_credentials(obfuscated=True) - } - - return list(tool_credential_dict.values()) - - -class ToolProviderCredentialsApi(Resource): + return ToolManageService.list_builtin_tool_provider_tools( + user_id, + tenant_id, + provider, + ) +class ToolBuiltinProviderDeleteApi(Resource): @setup_required @login_required @account_initialization_required def post(self, provider): - if provider not in [p.value for p in ToolProviderName]: - abort(404) - - # The role of the current user in the ta table must be admin or owner if current_user.current_tenant.current_role not in ['admin', 'owner']: - raise Forbidden(f'User {current_user.id} is not authorized to update provider token, ' - f'current_role is {current_user.current_tenant.current_role}') - - parser = reqparse.RequestParser() - parser.add_argument('credentials', type=dict, required=True, nullable=False, location='json') - args = parser.parse_args() - + raise Forbidden() + + user_id = current_user.id tenant_id = current_user.current_tenant_id - tool_provider_service = ToolProviderService(tenant_id, provider) - - try: - tool_provider_service.credentials_validate(args['credentials']) - except ToolValidateFailedError as ex: - raise ValueError(str(ex)) - - encrypted_credentials = json.dumps(tool_provider_service.encrypt_credentials(args['credentials'])) - - tenant = current_user.current_tenant - - tool_provider_model = db.session.query(ToolProvider).filter( - ToolProvider.tenant_id == tenant.id, - ToolProvider.tool_name == provider, - ).first() - - # Only allow updating token for CUSTOM provider type - if tool_provider_model: - tool_provider_model.encrypted_credentials = encrypted_credentials - tool_provider_model.is_enabled = True - else: - tool_provider_model = ToolProvider( - tenant_id=tenant.id, - tool_name=provider, - encrypted_credentials=encrypted_credentials, - is_enabled=True - ) - db.session.add(tool_provider_model) - - db.session.commit() - - return {'result': 'success'}, 201 - - -class ToolProviderCredentialsValidateApi(Resource): - + return ToolManageService.delete_builtin_tool_provider( + user_id, + tenant_id, + provider, + ) + +class ToolBuiltinProviderUpdateApi(Resource): @setup_required @login_required @account_initialization_required def post(self, provider): - if provider not in [p.value for p in ToolProviderName]: - abort(404) + if current_user.current_tenant.current_role not in ['admin', 'owner']: + raise Forbidden() + + user_id = current_user.id + tenant_id = current_user.current_tenant_id parser = reqparse.RequestParser() parser.add_argument('credentials', type=dict, required=True, nullable=False, location='json') + args = parser.parse_args() - result = True - error = None + return ToolManageService.update_builtin_tool_provider( + user_id, + tenant_id, + provider, + args['credentials'], + ) +class ToolBuiltinProviderIconApi(Resource): + @setup_required + def get(self, provider): + icon_bytes, minetype = ToolManageService.get_builtin_tool_provider_icon(provider) + return send_file(io.BytesIO(icon_bytes), mimetype=minetype) + + +class ToolApiProviderAddApi(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + if current_user.current_tenant.current_role not in ['admin', 'owner']: + raise Forbidden() + + user_id = current_user.id tenant_id = current_user.current_tenant_id - tool_provider_service = ToolProviderService(tenant_id, provider) + parser = reqparse.RequestParser() + parser.add_argument('credentials', type=dict, required=True, nullable=False, location='json') + parser.add_argument('schema_type', type=str, required=True, nullable=False, location='json') + parser.add_argument('schema', type=str, required=True, nullable=False, location='json') + parser.add_argument('provider', type=str, required=True, nullable=False, location='json') + parser.add_argument('icon', type=dict, required=True, nullable=False, location='json') + parser.add_argument('privacy_policy', type=str, required=False, nullable=True, location='json') - try: - tool_provider_service.credentials_validate(args['credentials']) - except ToolValidateFailedError as ex: - result = False - error = str(ex) + args = parser.parse_args() - response = {'result': 'success' if result else 'error'} + return ToolManageService.create_api_tool_provider( + user_id, + tenant_id, + args['provider'], + args['icon'], + args['credentials'], + args['schema_type'], + args['schema'], + args.get('privacy_policy', ''), + ) - if not result: - response['error'] = error +class ToolApiProviderGetRemoteSchemaApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self): + parser = reqparse.RequestParser() - return response + parser.add_argument('url', type=str, required=True, nullable=False, location='args') + args = parser.parse_args() + + return ToolManageService.get_api_tool_provider_remote_schema( + current_user.id, + current_user.current_tenant_id, + args['url'], + ) + +class ToolApiProviderListToolsApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self): + user_id = current_user.id + tenant_id = current_user.current_tenant_id + + parser = reqparse.RequestParser() + + parser.add_argument('provider', type=str, required=True, nullable=False, location='args') + + args = parser.parse_args() + + return ToolManageService.list_api_tool_provider_tools( + user_id, + tenant_id, + args['provider'], + ) + +class ToolApiProviderUpdateApi(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + if current_user.current_tenant.current_role not in ['admin', 'owner']: + raise Forbidden() + + user_id = current_user.id + tenant_id = current_user.current_tenant_id + + parser = reqparse.RequestParser() + parser.add_argument('credentials', type=dict, required=True, nullable=False, location='json') + parser.add_argument('schema_type', type=str, required=True, nullable=False, location='json') + parser.add_argument('schema', type=str, required=True, nullable=False, location='json') + parser.add_argument('provider', type=str, required=True, nullable=False, location='json') + parser.add_argument('original_provider', type=str, required=True, nullable=False, location='json') + parser.add_argument('icon', type=str, required=True, nullable=False, location='json') + parser.add_argument('privacy_policy', type=str, required=True, nullable=False, location='json') + + args = parser.parse_args() + + return ToolManageService.update_api_tool_provider( + user_id, + tenant_id, + args['provider'], + args['original_provider'], + args['icon'], + args['credentials'], + args['schema_type'], + args['schema'], + args['privacy_policy'], + ) + +class ToolApiProviderDeleteApi(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + if current_user.current_tenant.current_role not in ['admin', 'owner']: + raise Forbidden() + + user_id = current_user.id + tenant_id = current_user.current_tenant_id + + parser = reqparse.RequestParser() + + parser.add_argument('provider', type=str, required=True, nullable=False, location='json') + + args = parser.parse_args() + + return ToolManageService.delete_api_tool_provider( + user_id, + tenant_id, + args['provider'], + ) + +class ToolApiProviderGetApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self): + user_id = current_user.id + tenant_id = current_user.current_tenant_id + + parser = reqparse.RequestParser() + + parser.add_argument('provider', type=str, required=True, nullable=False, location='args') + + args = parser.parse_args() + + return ToolManageService.get_api_tool_provider( + user_id, + tenant_id, + args['provider'], + ) + +class ToolBuiltinProviderCredentialsSchemaApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self, provider): + return ToolManageService.list_builtin_provider_credentials_schema(provider) + +class ToolApiProviderSchemaApi(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + parser = reqparse.RequestParser() + + parser.add_argument('schema', type=str, required=True, nullable=False, location='json') + + args = parser.parse_args() + + return ToolManageService.parser_api_schema( + schema=args['schema'], + ) + +class ToolApiProviderPreviousTestApi(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + parser = reqparse.RequestParser() + + parser.add_argument('tool_name', type=str, required=True, nullable=False, location='json') + parser.add_argument('credentials', type=dict, required=True, nullable=False, location='json') + parser.add_argument('parameters', type=dict, required=True, nullable=False, location='json') + parser.add_argument('schema_type', type=str, required=True, nullable=False, location='json') + parser.add_argument('schema', type=str, required=True, nullable=False, location='json') + + args = parser.parse_args() + + return ToolManageService.test_api_tool_preview( + current_user.current_tenant_id, + args['tool_name'], + args['credentials'], + args['parameters'], + args['schema_type'], + args['schema'], + ) api.add_resource(ToolProviderListApi, '/workspaces/current/tool-providers') -api.add_resource(ToolProviderCredentialsApi, '/workspaces/current/tool-providers//credentials') -api.add_resource(ToolProviderCredentialsValidateApi, - '/workspaces/current/tool-providers//credentials-validate') +api.add_resource(ToolBuiltinProviderListToolsApi, '/workspaces/current/tool-provider/builtin//tools') +api.add_resource(ToolBuiltinProviderDeleteApi, '/workspaces/current/tool-provider/builtin//delete') +api.add_resource(ToolBuiltinProviderUpdateApi, '/workspaces/current/tool-provider/builtin//update') +api.add_resource(ToolBuiltinProviderCredentialsSchemaApi, '/workspaces/current/tool-provider/builtin//credentials_schema') +api.add_resource(ToolBuiltinProviderIconApi, '/workspaces/current/tool-provider/builtin//icon') +api.add_resource(ToolApiProviderAddApi, '/workspaces/current/tool-provider/api/add') +api.add_resource(ToolApiProviderGetRemoteSchemaApi, '/workspaces/current/tool-provider/api/remote') +api.add_resource(ToolApiProviderListToolsApi, '/workspaces/current/tool-provider/api/tools') +api.add_resource(ToolApiProviderUpdateApi, '/workspaces/current/tool-provider/api/update') +api.add_resource(ToolApiProviderDeleteApi, '/workspaces/current/tool-provider/api/delete') +api.add_resource(ToolApiProviderGetApi, '/workspaces/current/tool-provider/api/get') +api.add_resource(ToolApiProviderSchemaApi, '/workspaces/current/tool-provider/api/schema') +api.add_resource(ToolApiProviderPreviousTestApi, '/workspaces/current/tool-provider/api/test/pre') diff --git a/api/controllers/files/__init__.py b/api/controllers/files/__init__.py index ff8d54c72..7c3e848b5 100644 --- a/api/controllers/files/__init__.py +++ b/api/controllers/files/__init__.py @@ -7,3 +7,4 @@ api = ExternalApi(bp) from . import image_preview +from . import tool_files \ No newline at end of file diff --git a/api/controllers/files/tool_files.py b/api/controllers/files/tool_files.py new file mode 100644 index 000000000..f8b1936fc --- /dev/null +++ b/api/controllers/files/tool_files.py @@ -0,0 +1,47 @@ +from controllers.files import api +from flask import Response +from flask_restful import Resource, reqparse +from libs.exception import BaseHTTPException +from werkzeug.exceptions import NotFound, Forbidden + +from core.tools.tool_file_manager import ToolFileManager + +class ToolFilePreviewApi(Resource): + def get(self, file_id, extension): + file_id = str(file_id) + + parser = reqparse.RequestParser() + + parser.add_argument('timestamp', type=str, required=True, location='args') + parser.add_argument('nonce', type=str, required=True, location='args') + parser.add_argument('sign', type=str, required=True, location='args') + + args = parser.parse_args() + + if not ToolFileManager.verify_file(file_id=file_id, + timestamp=args['timestamp'], + nonce=args['nonce'], + sign=args['sign'], + ): + raise Forbidden('Invalid request.') + + try: + result = ToolFileManager.get_file_generator_by_message_file_id( + file_id, + ) + + if not result: + raise NotFound(f'file is not found') + + generator, mimetype = result + except Exception: + raise UnsupportedFileTypeError() + + return Response(generator, mimetype=mimetype) + +api.add_resource(ToolFilePreviewApi, '/files/tools/.') + +class UnsupportedFileTypeError(BaseHTTPException): + error_code = 'unsupported_file_type' + description = "File type not allowed." + code = 415 diff --git a/api/controllers/service_api/app/app.py b/api/controllers/service_api/app/app.py index 2809a9135..0be38d308 100644 --- a/api/controllers/service_api/app/app.py +++ b/api/controllers/service_api/app/app.py @@ -3,7 +3,12 @@ from controllers.service_api import api from controllers.service_api.wraps import AppApiResource from flask import current_app from flask_restful import fields, marshal_with -from models.model import App +from models.model import App, AppModelConfig +from models.tools import ApiToolProvider + +import json + +from extensions.ext_database import db class AppParameterApi(AppApiResource): @@ -58,5 +63,42 @@ class AppParameterApi(AppApiResource): } } +class AppMetaApi(AppApiResource): + def get(self, app_model: App, end_user): + """Get app meta""" + app_model_config: AppModelConfig = app_model.app_model_config + + agent_config = app_model_config.agent_mode_dict or {} + meta = { + 'tool_icons': {} + } + + # get all tools + tools = agent_config.get('tools', []) + url_prefix = (current_app.config.get("CONSOLE_API_URL") + + f"/console/api/workspaces/current/tool-provider/builtin/") + for tool in tools: + keys = list(tool.keys()) + if len(keys) >= 4: + # current tool standard + provider_type = tool.get('provider_type') + provider_id = tool.get('provider_id') + tool_name = tool.get('tool_name') + if provider_type == 'builtin': + meta['tool_icons'][tool_name] = url_prefix + provider_id + '/icon' + elif provider_type == 'api': + try: + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.id == provider_id + ) + meta['tool_icons'][tool_name] = json.loads(provider.icon) + except: + meta['tool_icons'][tool_name] = { + "background": "#252525", + "content": "\ud83d\ude01" + } + + return meta api.add_resource(AppParameterApi, '/parameters') +api.add_resource(AppMetaApi, '/meta') diff --git a/api/controllers/service_api/app/message.py b/api/controllers/service_api/app/message.py index 07c4318b8..aca995f99 100644 --- a/api/controllers/service_api/app/message.py +++ b/api/controllers/service_api/app/message.py @@ -37,6 +37,19 @@ class MessageListApi(AppApiResource): 'created_at': TimestampField } + agent_thought_fields = { + 'id': fields.String, + 'chain_id': fields.String, + 'message_id': fields.String, + 'position': fields.Integer, + 'thought': fields.String, + 'tool': fields.String, + 'tool_input': fields.String, + 'created_at': TimestampField, + 'observation': fields.String, + 'message_files': fields.List(fields.String, attribute='files') + } + message_fields = { 'id': fields.String, 'conversation_id': fields.String, @@ -46,7 +59,8 @@ class MessageListApi(AppApiResource): 'message_files': fields.List(fields.Nested(message_file_fields), attribute='files'), 'feedback': fields.Nested(feedback_fields, attribute='user_feedback', allow_null=True), 'retriever_resources': fields.List(fields.Nested(retriever_resource_fields)), - 'created_at': TimestampField + 'created_at': TimestampField, + 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)) } message_infinite_scroll_pagination_fields = { diff --git a/api/controllers/web/app.py b/api/controllers/web/app.py index 22b274c72..a51259f2e 100644 --- a/api/controllers/web/app.py +++ b/api/controllers/web/app.py @@ -3,7 +3,12 @@ from controllers.web import api from controllers.web.wraps import WebApiResource from flask import current_app from flask_restful import fields, marshal_with -from models.model import App +from models.model import App, AppModelConfig +from models.tools import ApiToolProvider + +from extensions.ext_database import db + +import json class AppParameterApi(WebApiResource): @@ -57,5 +62,42 @@ class AppParameterApi(WebApiResource): } } +class AppMeta(WebApiResource): + def get(self, app_model: App, end_user): + """Get app meta""" + app_model_config: AppModelConfig = app_model.app_model_config + + agent_config = app_model_config.agent_mode_dict or {} + meta = { + 'tool_icons': {} + } + + # get all tools + tools = agent_config.get('tools', []) + url_prefix = (current_app.config.get("CONSOLE_API_URL") + + f"/console/api/workspaces/current/tool-provider/builtin/") + for tool in tools: + keys = list(tool.keys()) + if len(keys) >= 4: + # current tool standard + provider_type = tool.get('provider_type') + provider_id = tool.get('provider_id') + tool_name = tool.get('tool_name') + if provider_type == 'builtin': + meta['tool_icons'][tool_name] = url_prefix + provider_id + '/icon' + elif provider_type == 'api': + try: + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.id == provider_id + ) + meta['tool_icons'][tool_name] = json.loads(provider.icon) + except: + meta['tool_icons'][tool_name] = { + "background": "#252525", + "content": "\ud83d\ude01" + } + + return meta api.add_resource(AppParameterApi, '/parameters') +api.add_resource(AppMeta, '/meta') \ No newline at end of file diff --git a/api/controllers/web/message.py b/api/controllers/web/message.py index f35493394..2712e8469 100644 --- a/api/controllers/web/message.py +++ b/api/controllers/web/message.py @@ -14,6 +14,7 @@ from core.entities.application_entities import InvokeFrom from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError from core.model_runtime.errors.invoke import InvokeError from fields.conversation_fields import message_file_fields +from fields.message_fields import agent_thought_fields from flask import Response, stream_with_context from flask_restful import fields, marshal_with, reqparse from flask_restful.inputs import int_range @@ -59,7 +60,8 @@ class MessageListApi(WebApiResource): 'message_files': fields.List(fields.Nested(message_file_fields), attribute='files'), 'feedback': fields.Nested(feedback_fields, attribute='user_feedback', allow_null=True), 'retriever_resources': fields.List(fields.Nested(retriever_resource_fields)), - 'created_at': TimestampField + 'created_at': TimestampField, + 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)) } message_infinite_scroll_pagination_fields = { diff --git a/api/core/agent/agent_executor.py b/api/core/agent/agent_executor.py index 4aa48337e..2565fb231 100644 --- a/api/core/agent/agent_executor.py +++ b/api/core/agent/agent_executor.py @@ -13,8 +13,8 @@ from core.entities.message_entities import prompt_messages_to_lc_messages from core.helper import moderation from core.memory.token_buffer_memory import TokenBufferMemory from core.model_runtime.errors.invoke import InvokeError -from core.tool.dataset_multi_retriever_tool import DatasetMultiRetrieverTool -from core.tool.dataset_retriever_tool import DatasetRetrieverTool +from core.tools.tool.dataset_retriever.dataset_multi_retriever_tool import DatasetMultiRetrieverTool +from core.tools.tool.dataset_retriever.dataset_retriever_tool import DatasetRetrieverTool from langchain.agents import AgentExecutor as LCAgentExecutor from langchain.agents import BaseMultiActionAgent, BaseSingleActionAgent from langchain.callbacks.manager import Callbacks diff --git a/api/core/app_runner/agent_app_runner.py b/api/core/app_runner/agent_app_runner.py deleted file mode 100644 index cc375056c..000000000 --- a/api/core/app_runner/agent_app_runner.py +++ /dev/null @@ -1,251 +0,0 @@ -import json -import logging -from typing import cast - -from core.agent.agent.agent_llm_callback import AgentLLMCallback -from core.app_runner.app_runner import AppRunner -from core.application_queue_manager import ApplicationQueueManager -from core.callback_handler.agent_loop_gather_callback_handler import AgentLoopGatherCallbackHandler -from core.entities.application_entities import ApplicationGenerateEntity, ModelConfigEntity, PromptTemplateEntity -from core.features.agent_runner import AgentRunnerFeature -from core.memory.token_buffer_memory import TokenBufferMemory -from core.model_manager import ModelInstance -from core.model_runtime.entities.llm_entities import LLMUsage -from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel -from extensions.ext_database import db -from models.model import App, Conversation, Message, MessageAgentThought, MessageChain - -logger = logging.getLogger(__name__) - - -class AgentApplicationRunner(AppRunner): - """ - Agent Application Runner - """ - - def run(self, application_generate_entity: ApplicationGenerateEntity, - queue_manager: ApplicationQueueManager, - conversation: Conversation, - message: Message) -> None: - """ - Run agent application - :param application_generate_entity: application generate entity - :param queue_manager: application queue manager - :param conversation: conversation - :param message: message - :return: - """ - app_record = db.session.query(App).filter(App.id == application_generate_entity.app_id).first() - if not app_record: - raise ValueError(f"App not found") - - app_orchestration_config = application_generate_entity.app_orchestration_config_entity - - inputs = application_generate_entity.inputs - query = application_generate_entity.query - files = application_generate_entity.files - - # Pre-calculate the number of tokens of the prompt messages, - # and return the rest number of tokens by model context token size limit and max token size limit. - # If the rest number of tokens is not enough, raise exception. - # Include: prompt template, inputs, query(optional), files(optional) - # Not Include: memory, external data, dataset context - self.get_pre_calculate_rest_tokens( - app_record=app_record, - model_config=app_orchestration_config.model_config, - prompt_template_entity=app_orchestration_config.prompt_template, - inputs=inputs, - files=files, - query=query - ) - - memory = None - if application_generate_entity.conversation_id: - # get memory of conversation (read-only) - model_instance = ModelInstance( - provider_model_bundle=app_orchestration_config.model_config.provider_model_bundle, - model=app_orchestration_config.model_config.model - ) - - memory = TokenBufferMemory( - conversation=conversation, - model_instance=model_instance - ) - - # reorganize all inputs and template to prompt messages - # Include: prompt template, inputs, query(optional), files(optional) - # memory(optional) - prompt_messages, stop = self.organize_prompt_messages( - app_record=app_record, - model_config=app_orchestration_config.model_config, - prompt_template_entity=app_orchestration_config.prompt_template, - inputs=inputs, - files=files, - query=query, - context=None, - memory=memory - ) - - # Create MessageChain - message_chain = self._init_message_chain( - message=message, - query=query - ) - - # add agent callback to record agent thoughts - agent_callback = AgentLoopGatherCallbackHandler( - model_config=app_orchestration_config.model_config, - message=message, - queue_manager=queue_manager, - message_chain=message_chain - ) - - # init LLM Callback - agent_llm_callback = AgentLLMCallback( - agent_callback=agent_callback - ) - - agent_runner = AgentRunnerFeature( - tenant_id=application_generate_entity.tenant_id, - app_orchestration_config=app_orchestration_config, - model_config=app_orchestration_config.model_config, - config=app_orchestration_config.agent, - queue_manager=queue_manager, - message=message, - user_id=application_generate_entity.user_id, - agent_llm_callback=agent_llm_callback, - callback=agent_callback, - memory=memory - ) - - # agent run - result = agent_runner.run( - query=query, - invoke_from=application_generate_entity.invoke_from - ) - - if result: - self._save_message_chain( - message_chain=message_chain, - output_text=result - ) - - if (result - and app_orchestration_config.prompt_template.prompt_type == PromptTemplateEntity.PromptType.SIMPLE - and app_orchestration_config.prompt_template.simple_prompt_template - ): - # Direct output if agent result exists and has pre prompt - self.direct_output( - queue_manager=queue_manager, - app_orchestration_config=app_orchestration_config, - prompt_messages=prompt_messages, - stream=application_generate_entity.stream, - text=result, - usage=self._get_usage_of_all_agent_thoughts( - model_config=app_orchestration_config.model_config, - message=message - ) - ) - else: - # As normal LLM run, agent result as context - context = result - - # reorganize all inputs and template to prompt messages - # Include: prompt template, inputs, query(optional), files(optional) - # memory(optional), external data, dataset context(optional) - prompt_messages, stop = self.organize_prompt_messages( - app_record=app_record, - model_config=app_orchestration_config.model_config, - prompt_template_entity=app_orchestration_config.prompt_template, - inputs=inputs, - files=files, - query=query, - context=context, - memory=memory - ) - - # Re-calculate the max tokens if sum(prompt_token + max_tokens) over model token limit - self.recale_llm_max_tokens( - model_config=app_orchestration_config.model_config, - prompt_messages=prompt_messages - ) - - # Invoke model - model_instance = ModelInstance( - provider_model_bundle=app_orchestration_config.model_config.provider_model_bundle, - model=app_orchestration_config.model_config.model - ) - - invoke_result = model_instance.invoke_llm( - prompt_messages=prompt_messages, - model_parameters=app_orchestration_config.model_config.parameters, - stop=stop, - stream=application_generate_entity.stream, - user=application_generate_entity.user_id, - ) - - # handle invoke result - self._handle_invoke_result( - invoke_result=invoke_result, - queue_manager=queue_manager, - stream=application_generate_entity.stream - ) - - def _init_message_chain(self, message: Message, query: str) -> MessageChain: - """ - Init MessageChain - :param message: message - :param query: query - :return: - """ - message_chain = MessageChain( - message_id=message.id, - type="AgentExecutor", - input=json.dumps({ - "input": query - }) - ) - - db.session.add(message_chain) - db.session.commit() - - return message_chain - - def _save_message_chain(self, message_chain: MessageChain, output_text: str) -> None: - """ - Save MessageChain - :param message_chain: message chain - :param output_text: output text - :return: - """ - message_chain.output = json.dumps({ - "output": output_text - }) - db.session.commit() - - def _get_usage_of_all_agent_thoughts(self, model_config: ModelConfigEntity, - message: Message) -> LLMUsage: - """ - Get usage of all agent thoughts - :param model_config: model config - :param message: message - :return: - """ - agent_thoughts = (db.session.query(MessageAgentThought) - .filter(MessageAgentThought.message_id == message.id).all()) - - all_message_tokens = 0 - all_answer_tokens = 0 - for agent_thought in agent_thoughts: - all_message_tokens += agent_thought.message_token - all_answer_tokens += agent_thought.answer_token - - model_type_instance = model_config.provider_model_bundle.model_type_instance - model_type_instance = cast(LargeLanguageModel, model_type_instance) - - return model_type_instance._calc_response_usage( - model_config.model, - model_config.credentials, - all_message_tokens, - all_answer_tokens - ) diff --git a/api/core/app_runner/app_runner.py b/api/core/app_runner/app_runner.py index a2edbfc3a..c7c5474b2 100644 --- a/api/core/app_runner/app_runner.py +++ b/api/core/app_runner/app_runner.py @@ -2,7 +2,8 @@ import time from typing import Generator, List, Optional, Tuple, Union, cast from core.application_queue_manager import ApplicationQueueManager, PublishFrom -from core.entities.application_entities import AppOrchestrationConfigEntity, ModelConfigEntity, PromptTemplateEntity +from core.entities.application_entities import AppOrchestrationConfigEntity, ModelConfigEntity, \ + PromptTemplateEntity, ExternalDataVariableEntity, ApplicationGenerateEntity, InvokeFrom from core.file.file_obj import FileObj from core.memory.token_buffer_memory import TokenBufferMemory from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta, LLMUsage @@ -10,9 +11,12 @@ from core.model_runtime.entities.message_entities import AssistantPromptMessage, from core.model_runtime.entities.model_entities import ModelPropertyKey from core.model_runtime.errors.invoke import InvokeBadRequestError from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel +from core.features.hosting_moderation import HostingModerationFeature +from core.features.moderation import ModerationFeature +from core.features.external_data_fetch import ExternalDataFetchFeature +from core.features.annotation_reply import AnnotationReplyFeature from core.prompt.prompt_transform import PromptTransform -from models.model import App - +from models.model import App, MessageAnnotation, Message class AppRunner: def get_pre_calculate_rest_tokens(self, app_record: App, @@ -199,7 +203,8 @@ class AppRunner: def _handle_invoke_result(self, invoke_result: Union[LLMResult, Generator], queue_manager: ApplicationQueueManager, - stream: bool) -> None: + stream: bool, + agent: bool = False) -> None: """ Handle invoke result :param invoke_result: invoke result @@ -210,16 +215,19 @@ class AppRunner: if not stream: self._handle_invoke_result_direct( invoke_result=invoke_result, - queue_manager=queue_manager + queue_manager=queue_manager, + agent=agent ) else: self._handle_invoke_result_stream( invoke_result=invoke_result, - queue_manager=queue_manager + queue_manager=queue_manager, + agent=agent ) def _handle_invoke_result_direct(self, invoke_result: LLMResult, - queue_manager: ApplicationQueueManager) -> None: + queue_manager: ApplicationQueueManager, + agent: bool) -> None: """ Handle invoke result direct :param invoke_result: invoke result @@ -232,7 +240,8 @@ class AppRunner: ) def _handle_invoke_result_stream(self, invoke_result: Generator, - queue_manager: ApplicationQueueManager) -> None: + queue_manager: ApplicationQueueManager, + agent: bool) -> None: """ Handle invoke result :param invoke_result: invoke result @@ -244,7 +253,10 @@ class AppRunner: text = '' usage = None for result in invoke_result: - queue_manager.publish_chunk_message(result, PublishFrom.APPLICATION_MANAGER) + if not agent: + queue_manager.publish_chunk_message(result, PublishFrom.APPLICATION_MANAGER) + else: + queue_manager.publish_agent_chunk_message(result, PublishFrom.APPLICATION_MANAGER) text += result.delta.message.content @@ -271,3 +283,101 @@ class AppRunner: llm_result=llm_result, pub_from=PublishFrom.APPLICATION_MANAGER ) + + def moderation_for_inputs(self, app_id: str, + tenant_id: str, + app_orchestration_config_entity: AppOrchestrationConfigEntity, + inputs: dict, + query: str) -> Tuple[bool, dict, str]: + """ + Process sensitive_word_avoidance. + :param app_id: app id + :param tenant_id: tenant id + :param app_orchestration_config_entity: app orchestration config entity + :param inputs: inputs + :param query: query + :return: + """ + moderation_feature = ModerationFeature() + return moderation_feature.check( + app_id=app_id, + tenant_id=tenant_id, + app_orchestration_config_entity=app_orchestration_config_entity, + inputs=inputs, + query=query, + ) + + def check_hosting_moderation(self, application_generate_entity: ApplicationGenerateEntity, + queue_manager: ApplicationQueueManager, + prompt_messages: list[PromptMessage]) -> bool: + """ + Check hosting moderation + :param application_generate_entity: application generate entity + :param queue_manager: queue manager + :param prompt_messages: prompt messages + :return: + """ + hosting_moderation_feature = HostingModerationFeature() + moderation_result = hosting_moderation_feature.check( + application_generate_entity=application_generate_entity, + prompt_messages=prompt_messages + ) + + if moderation_result: + self.direct_output( + queue_manager=queue_manager, + app_orchestration_config=application_generate_entity.app_orchestration_config_entity, + prompt_messages=prompt_messages, + text="I apologize for any confusion, " \ + "but I'm an AI assistant to be helpful, harmless, and honest.", + stream=application_generate_entity.stream + ) + + return moderation_result + + def fill_in_inputs_from_external_data_tools(self, tenant_id: str, + app_id: str, + external_data_tools: list[ExternalDataVariableEntity], + inputs: dict, + query: str) -> dict: + """ + Fill in variable inputs from external data tools if exists. + + :param tenant_id: workspace id + :param app_id: app id + :param external_data_tools: external data tools configs + :param inputs: the inputs + :param query: the query + :return: the filled inputs + """ + external_data_fetch_feature = ExternalDataFetchFeature() + return external_data_fetch_feature.fetch( + tenant_id=tenant_id, + app_id=app_id, + external_data_tools=external_data_tools, + inputs=inputs, + query=query + ) + + def query_app_annotations_to_reply(self, app_record: App, + message: Message, + query: str, + user_id: str, + invoke_from: InvokeFrom) -> Optional[MessageAnnotation]: + """ + Query app annotations to reply + :param app_record: app record + :param message: message + :param query: query + :param user_id: user id + :param invoke_from: invoke from + :return: + """ + annotation_reply_feature = AnnotationReplyFeature() + return annotation_reply_feature.query( + app_record=app_record, + message=message, + query=query, + user_id=user_id, + invoke_from=invoke_from + ) \ No newline at end of file diff --git a/api/core/app_runner/assistant_app_runner.py b/api/core/app_runner/assistant_app_runner.py new file mode 100644 index 000000000..24da55636 --- /dev/null +++ b/api/core/app_runner/assistant_app_runner.py @@ -0,0 +1,342 @@ +import json +import logging +from typing import cast + +from core.app_runner.app_runner import AppRunner +from core.features.assistant_cot_runner import AssistantCotApplicationRunner +from core.features.assistant_fc_runner import AssistantFunctionCallApplicationRunner +from core.entities.application_entities import ApplicationGenerateEntity, ModelConfigEntity, \ + AgentEntity +from core.application_queue_manager import ApplicationQueueManager, PublishFrom +from core.memory.token_buffer_memory import TokenBufferMemory +from core.model_manager import ModelInstance +from core.model_runtime.entities.llm_entities import LLMUsage +from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel +from core.moderation.base import ModerationException +from core.tools.entities.tool_entities import ToolRuntimeVariablePool +from extensions.ext_database import db +from models.model import Conversation, Message, App, MessageChain, MessageAgentThought +from models.tools import ToolConversationVariables + +logger = logging.getLogger(__name__) + +class AssistantApplicationRunner(AppRunner): + """ + Assistant Application Runner + """ + def run(self, application_generate_entity: ApplicationGenerateEntity, + queue_manager: ApplicationQueueManager, + conversation: Conversation, + message: Message) -> None: + """ + Run assistant application + :param application_generate_entity: application generate entity + :param queue_manager: application queue manager + :param conversation: conversation + :param message: message + :return: + """ + app_record = db.session.query(App).filter(App.id == application_generate_entity.app_id).first() + if not app_record: + raise ValueError(f"App not found") + + app_orchestration_config = application_generate_entity.app_orchestration_config_entity + + inputs = application_generate_entity.inputs + query = application_generate_entity.query + files = application_generate_entity.files + + # Pre-calculate the number of tokens of the prompt messages, + # and return the rest number of tokens by model context token size limit and max token size limit. + # If the rest number of tokens is not enough, raise exception. + # Include: prompt template, inputs, query(optional), files(optional) + # Not Include: memory, external data, dataset context + self.get_pre_calculate_rest_tokens( + app_record=app_record, + model_config=app_orchestration_config.model_config, + prompt_template_entity=app_orchestration_config.prompt_template, + inputs=inputs, + files=files, + query=query + ) + + memory = None + if application_generate_entity.conversation_id: + # get memory of conversation (read-only) + model_instance = ModelInstance( + provider_model_bundle=app_orchestration_config.model_config.provider_model_bundle, + model=app_orchestration_config.model_config.model + ) + + memory = TokenBufferMemory( + conversation=conversation, + model_instance=model_instance + ) + + # organize all inputs and template to prompt messages + # Include: prompt template, inputs, query(optional), files(optional) + # memory(optional) + prompt_messages, _ = self.organize_prompt_messages( + app_record=app_record, + model_config=app_orchestration_config.model_config, + prompt_template_entity=app_orchestration_config.prompt_template, + inputs=inputs, + files=files, + query=query, + memory=memory + ) + + # moderation + try: + # process sensitive_word_avoidance + _, inputs, query = self.moderation_for_inputs( + app_id=app_record.id, + tenant_id=application_generate_entity.tenant_id, + app_orchestration_config_entity=app_orchestration_config, + inputs=inputs, + query=query, + ) + except ModerationException as e: + self.direct_output( + queue_manager=queue_manager, + app_orchestration_config=app_orchestration_config, + prompt_messages=prompt_messages, + text=str(e), + stream=application_generate_entity.stream + ) + return + + if query: + # annotation reply + annotation_reply = self.query_app_annotations_to_reply( + app_record=app_record, + message=message, + query=query, + user_id=application_generate_entity.user_id, + invoke_from=application_generate_entity.invoke_from + ) + + if annotation_reply: + queue_manager.publish_annotation_reply( + message_annotation_id=annotation_reply.id, + pub_from=PublishFrom.APPLICATION_MANAGER + ) + self.direct_output( + queue_manager=queue_manager, + app_orchestration_config=app_orchestration_config, + prompt_messages=prompt_messages, + text=annotation_reply.content, + stream=application_generate_entity.stream + ) + return + + # fill in variable inputs from external data tools if exists + external_data_tools = app_orchestration_config.external_data_variables + if external_data_tools: + inputs = self.fill_in_inputs_from_external_data_tools( + tenant_id=app_record.tenant_id, + app_id=app_record.id, + external_data_tools=external_data_tools, + inputs=inputs, + query=query + ) + + # reorganize all inputs and template to prompt messages + # Include: prompt template, inputs, query(optional), files(optional) + # memory(optional), external data, dataset context(optional) + prompt_messages, _ = self.organize_prompt_messages( + app_record=app_record, + model_config=app_orchestration_config.model_config, + prompt_template_entity=app_orchestration_config.prompt_template, + inputs=inputs, + files=files, + query=query, + memory=memory + ) + + # check hosting moderation + hosting_moderation_result = self.check_hosting_moderation( + application_generate_entity=application_generate_entity, + queue_manager=queue_manager, + prompt_messages=prompt_messages + ) + + if hosting_moderation_result: + return + + agent_entity = app_orchestration_config.agent + + # load tool variables + tool_conversation_variables = self._load_tool_variables(conversation_id=conversation.id, + user_id=application_generate_entity.user_id, + tanent_id=application_generate_entity.tenant_id) + + # convert db variables to tool variables + tool_variables = self._convert_db_variables_to_tool_variables(tool_conversation_variables) + + message_chain = self._init_message_chain( + message=message, + query=query + ) + + # init model instance + model_instance = ModelInstance( + provider_model_bundle=app_orchestration_config.model_config.provider_model_bundle, + model=app_orchestration_config.model_config.model + ) + prompt_message, _ = self.organize_prompt_messages( + app_record=app_record, + model_config=app_orchestration_config.model_config, + prompt_template_entity=app_orchestration_config.prompt_template, + inputs=inputs, + files=files, + query=query, + memory=memory, + ) + + # start agent runner + if agent_entity.strategy == AgentEntity.Strategy.CHAIN_OF_THOUGHT: + assistant_cot_runner = AssistantCotApplicationRunner( + tenant_id=application_generate_entity.tenant_id, + application_generate_entity=application_generate_entity, + app_orchestration_config=app_orchestration_config, + model_config=app_orchestration_config.model_config, + config=agent_entity, + queue_manager=queue_manager, + message=message, + user_id=application_generate_entity.user_id, + memory=memory, + prompt_messages=prompt_message, + variables_pool=tool_variables, + db_variables=tool_conversation_variables, + ) + invoke_result = assistant_cot_runner.run( + model_instance=model_instance, + conversation=conversation, + message=message, + query=query, + ) + elif agent_entity.strategy == AgentEntity.Strategy.FUNCTION_CALLING: + assistant_cot_runner = AssistantFunctionCallApplicationRunner( + tenant_id=application_generate_entity.tenant_id, + application_generate_entity=application_generate_entity, + app_orchestration_config=app_orchestration_config, + model_config=app_orchestration_config.model_config, + config=agent_entity, + queue_manager=queue_manager, + message=message, + user_id=application_generate_entity.user_id, + memory=memory, + prompt_messages=prompt_message, + variables_pool=tool_variables, + db_variables=tool_conversation_variables + ) + invoke_result = assistant_cot_runner.run( + model_instance=model_instance, + conversation=conversation, + message=message, + query=query, + ) + + # handle invoke result + self._handle_invoke_result( + invoke_result=invoke_result, + queue_manager=queue_manager, + stream=application_generate_entity.stream, + agent=True + ) + + def _load_tool_variables(self, conversation_id: str, user_id: str, tanent_id: str) -> ToolConversationVariables: + """ + load tool variables from database + """ + tool_variables: ToolConversationVariables = db.session.query(ToolConversationVariables).filter( + ToolConversationVariables.conversation_id == conversation_id, + ToolConversationVariables.tenant_id == tanent_id + ).first() + + if tool_variables: + # save tool variables to session, so that we can update it later + db.session.add(tool_variables) + else: + # create new tool variables + tool_variables = ToolConversationVariables( + conversation_id=conversation_id, + user_id=user_id, + tenant_id=tanent_id, + variables_str='[]', + ) + db.session.add(tool_variables) + db.session.commit() + + return tool_variables + + def _convert_db_variables_to_tool_variables(self, db_variables: ToolConversationVariables) -> ToolRuntimeVariablePool: + """ + convert db variables to tool variables + """ + return ToolRuntimeVariablePool(**{ + 'conversation_id': db_variables.conversation_id, + 'user_id': db_variables.user_id, + 'tenant_id': db_variables.tenant_id, + 'pool': db_variables.variables + }) + + def _init_message_chain(self, message: Message, query: str) -> MessageChain: + """ + Init MessageChain + :param message: message + :param query: query + :return: + """ + message_chain = MessageChain( + message_id=message.id, + type="AgentExecutor", + input=json.dumps({ + "input": query + }) + ) + + db.session.add(message_chain) + db.session.commit() + + return message_chain + + def _save_message_chain(self, message_chain: MessageChain, output_text: str) -> None: + """ + Save MessageChain + :param message_chain: message chain + :param output_text: output text + :return: + """ + message_chain.output = json.dumps({ + "output": output_text + }) + db.session.commit() + + def _get_usage_of_all_agent_thoughts(self, model_config: ModelConfigEntity, + message: Message) -> LLMUsage: + """ + Get usage of all agent thoughts + :param model_config: model config + :param message: message + :return: + """ + agent_thoughts = (db.session.query(MessageAgentThought) + .filter(MessageAgentThought.message_id == message.id).all()) + + all_message_tokens = 0 + all_answer_tokens = 0 + for agent_thought in agent_thoughts: + all_message_tokens += agent_thought.message_tokens + all_answer_tokens += agent_thought.answer_tokens + + model_type_instance = model_config.provider_model_bundle.model_type_instance + model_type_instance = cast(LargeLanguageModel, model_type_instance) + + return model_type_instance._calc_response_usage( + model_config.model, + model_config.credentials, + all_message_tokens, + all_answer_tokens + ) diff --git a/api/core/app_runner/basic_app_runner.py b/api/core/app_runner/basic_app_runner.py index 97d684a37..086478653 100644 --- a/api/core/app_runner/basic_app_runner.py +++ b/api/core/app_runner/basic_app_runner.py @@ -1,23 +1,18 @@ import logging -from typing import Optional, Tuple +from typing import Optional from core.app_runner.app_runner import AppRunner from core.application_queue_manager import ApplicationQueueManager, PublishFrom from core.callback_handler.index_tool_callback_handler import DatasetIndexToolCallbackHandler -from core.entities.application_entities import (ApplicationGenerateEntity, AppOrchestrationConfigEntity, DatasetEntity, - ExternalDataVariableEntity, InvokeFrom, ModelConfigEntity) -from core.features.annotation_reply import AnnotationReplyFeature +from core.entities.application_entities import (ApplicationGenerateEntity, DatasetEntity, + InvokeFrom, ModelConfigEntity) from core.features.dataset_retrieval import DatasetRetrievalFeature -from core.features.external_data_fetch import ExternalDataFetchFeature -from core.features.hosting_moderation import HostingModerationFeature -from core.features.moderation import ModerationFeature from core.memory.token_buffer_memory import TokenBufferMemory from core.model_manager import ModelInstance -from core.model_runtime.entities.message_entities import PromptMessage from core.moderation.base import ModerationException from core.prompt.prompt_transform import AppMode from extensions.ext_database import db -from models.model import App, Conversation, Message, MessageAnnotation +from models.model import App, Conversation, Message logger = logging.getLogger(__name__) @@ -213,76 +208,6 @@ class BasicApplicationRunner(AppRunner): stream=application_generate_entity.stream ) - def moderation_for_inputs(self, app_id: str, - tenant_id: str, - app_orchestration_config_entity: AppOrchestrationConfigEntity, - inputs: dict, - query: str) -> Tuple[bool, dict, str]: - """ - Process sensitive_word_avoidance. - :param app_id: app id - :param tenant_id: tenant id - :param app_orchestration_config_entity: app orchestration config entity - :param inputs: inputs - :param query: query - :return: - """ - moderation_feature = ModerationFeature() - return moderation_feature.check( - app_id=app_id, - tenant_id=tenant_id, - app_orchestration_config_entity=app_orchestration_config_entity, - inputs=inputs, - query=query, - ) - - def query_app_annotations_to_reply(self, app_record: App, - message: Message, - query: str, - user_id: str, - invoke_from: InvokeFrom) -> Optional[MessageAnnotation]: - """ - Query app annotations to reply - :param app_record: app record - :param message: message - :param query: query - :param user_id: user id - :param invoke_from: invoke from - :return: - """ - annotation_reply_feature = AnnotationReplyFeature() - return annotation_reply_feature.query( - app_record=app_record, - message=message, - query=query, - user_id=user_id, - invoke_from=invoke_from - ) - - def fill_in_inputs_from_external_data_tools(self, tenant_id: str, - app_id: str, - external_data_tools: list[ExternalDataVariableEntity], - inputs: dict, - query: str) -> dict: - """ - Fill in variable inputs from external data tools if exists. - - :param tenant_id: workspace id - :param app_id: app id - :param external_data_tools: external data tools configs - :param inputs: the inputs - :param query: the query - :return: the filled inputs - """ - external_data_fetch_feature = ExternalDataFetchFeature() - return external_data_fetch_feature.fetch( - tenant_id=tenant_id, - app_id=app_id, - external_data_tools=external_data_tools, - inputs=inputs, - query=query - ) - def retrieve_dataset_context(self, tenant_id: str, app_record: App, queue_manager: ApplicationQueueManager, @@ -334,31 +259,4 @@ class BasicApplicationRunner(AppRunner): hit_callback=hit_callback, memory=memory ) - - def check_hosting_moderation(self, application_generate_entity: ApplicationGenerateEntity, - queue_manager: ApplicationQueueManager, - prompt_messages: list[PromptMessage]) -> bool: - """ - Check hosting moderation - :param application_generate_entity: application generate entity - :param queue_manager: queue manager - :param prompt_messages: prompt messages - :return: - """ - hosting_moderation_feature = HostingModerationFeature() - moderation_result = hosting_moderation_feature.check( - application_generate_entity=application_generate_entity, - prompt_messages=prompt_messages - ) - - if moderation_result: - self.direct_output( - queue_manager=queue_manager, - app_orchestration_config=application_generate_entity.app_orchestration_config_entity, - prompt_messages=prompt_messages, - text="I apologize for any confusion, " \ - "but I'm an AI assistant to be helpful, harmless, and honest.", - stream=application_generate_entity.stream - ) - - return moderation_result + \ No newline at end of file diff --git a/api/core/app_runner/generate_task_pipeline.py b/api/core/app_runner/generate_task_pipeline.py index 0e84c1c4c..58a99a52c 100644 --- a/api/core/app_runner/generate_task_pipeline.py +++ b/api/core/app_runner/generate_task_pipeline.py @@ -8,7 +8,8 @@ from core.application_queue_manager import ApplicationQueueManager, PublishFrom from core.entities.application_entities import ApplicationGenerateEntity, InvokeFrom from core.entities.queue_entities import (AnnotationReplyEvent, QueueAgentThoughtEvent, QueueErrorEvent, QueueMessageEndEvent, QueueMessageEvent, QueueMessageReplaceEvent, - QueuePingEvent, QueueRetrieverResourcesEvent, QueueStopEvent) + QueuePingEvent, QueueRetrieverResourcesEvent, QueueStopEvent, + QueueMessageFileEvent, QueueAgentMessageEvent) from core.errors.error import ProviderTokenNotInitError, QuotaExceededError, ModelCurrentlyNotSupportError from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta, LLMUsage from core.model_runtime.entities.message_entities import (AssistantPromptMessage, ImagePromptMessageContent, @@ -16,11 +17,12 @@ from core.model_runtime.entities.message_entities import (AssistantPromptMessage TextPromptMessageContent) from core.model_runtime.errors.invoke import InvokeAuthorizationError, InvokeError from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel +from core.tools.tool_file_manager import ToolFileManager from core.model_runtime.utils.encoders import jsonable_encoder from core.prompt.prompt_template import PromptTemplateParser from events.message_event import message_was_created from extensions.ext_database import db -from models.model import Conversation, Message, MessageAgentThought +from models.model import Conversation, Message, MessageAgentThought, MessageFile from pydantic import BaseModel from services.annotation_service import AppAnnotationService @@ -284,6 +286,7 @@ class GenerateTaskPipeline: .filter(MessageAgentThought.id == event.agent_thought_id) .first() ) + db.session.refresh(agent_thought) if agent_thought: response = { @@ -293,16 +296,48 @@ class GenerateTaskPipeline: 'message_id': self._message.id, 'position': agent_thought.position, 'thought': agent_thought.thought, + 'observation': agent_thought.observation, 'tool': agent_thought.tool, 'tool_input': agent_thought.tool_input, - 'created_at': int(self._message.created_at.timestamp()) + 'created_at': int(self._message.created_at.timestamp()), + 'message_files': agent_thought.files } if self._conversation.mode == 'chat': response['conversation_id'] = self._conversation.id yield self._yield_response(response) - elif isinstance(event, QueueMessageEvent): + elif isinstance(event, QueueMessageFileEvent): + message_file: MessageFile = ( + db.session.query(MessageFile) + .filter(MessageFile.id == event.message_file_id) + .first() + ) + # get extension + if '.' in message_file.url: + extension = f'.{message_file.url.split(".")[-1]}' + if len(extension) > 10: + extension = '.bin' + else: + extension = '.bin' + # add sign url + url = ToolFileManager.sign_file(file_id=message_file.id, extension=extension) + + if message_file: + response = { + 'event': 'message_file', + 'id': message_file.id, + 'type': message_file.type, + 'belongs_to': message_file.belongs_to or 'user', + 'url': url + } + + if self._conversation.mode == 'chat': + response['conversation_id'] = self._conversation.id + + yield self._yield_response(response) + + elif isinstance(event, (QueueMessageEvent, QueueAgentMessageEvent)): chunk = event.chunk delta_text = chunk.delta.message.content if delta_text is None: @@ -332,7 +367,7 @@ class GenerateTaskPipeline: self._output_moderation_handler.append_new_token(delta_text) self._task_state.llm_result.message.content += delta_text - response = self._handle_chunk(delta_text) + response = self._handle_chunk(delta_text, agent=isinstance(event, QueueAgentMessageEvent)) yield self._yield_response(response) elif isinstance(event, QueueMessageReplaceEvent): response = { @@ -384,14 +419,14 @@ class GenerateTaskPipeline: extras=self._application_generate_entity.extras ) - def _handle_chunk(self, text: str) -> dict: + def _handle_chunk(self, text: str, agent: bool = False) -> dict: """ Handle completed event. :param text: text :return: """ response = { - 'event': 'message', + 'event': 'message' if not agent else 'agent_message', 'id': self._message.id, 'task_id': self._application_generate_entity.task_id, 'message_id': self._message.id, diff --git a/api/core/application_manager.py b/api/core/application_manager.py index 7a0bed3de..100725f6d 100644 --- a/api/core/application_manager.py +++ b/api/core/application_manager.py @@ -4,7 +4,7 @@ import threading import uuid from typing import Any, Generator, Optional, Tuple, Union, cast -from core.app_runner.agent_app_runner import AgentApplicationRunner +from core.app_runner.assistant_app_runner import AssistantApplicationRunner from core.app_runner.basic_app_runner import BasicApplicationRunner from core.app_runner.generate_task_pipeline import GenerateTaskPipeline from core.application_queue_manager import ApplicationQueueManager, ConversationTaskStoppedException, PublishFrom @@ -13,7 +13,7 @@ from core.entities.application_entities import (AdvancedChatPromptTemplateEntity ApplicationGenerateEntity, AppOrchestrationConfigEntity, DatasetEntity, DatasetRetrieveConfigEntity, ExternalDataVariableEntity, FileUploadEntity, InvokeFrom, ModelConfigEntity, PromptTemplateEntity, - SensitiveWordAvoidanceEntity) + SensitiveWordAvoidanceEntity, AgentPromptEntity) from core.entities.model_entities import ModelStatus from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError from core.file.file_obj import FileObj @@ -23,6 +23,7 @@ from core.model_runtime.errors.invoke import InvokeAuthorizationError, InvokeErr from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel from core.prompt.prompt_template import PromptTemplateParser from core.provider_manager import ProviderManager +from core.tools.prompt.template import REACT_PROMPT_TEMPLATES from extensions.ext_database import db from flask import Flask, current_app from models.account import Account @@ -93,6 +94,9 @@ class ApplicationManager: extras=extras ) + if not stream and application_generate_entity.app_orchestration_config_entity.agent: + raise ValueError("Agent app is not supported in blocking mode.") + # init generate records ( conversation, @@ -151,7 +155,7 @@ class ApplicationManager: if application_generate_entity.app_orchestration_config_entity.agent: # agent app - runner = AgentApplicationRunner() + runner = AssistantApplicationRunner() runner.run( application_generate_entity=application_generate_entity, queue_manager=queue_manager, @@ -354,6 +358,8 @@ class ApplicationManager: # external data variables properties['external_data_variables'] = [] + + # old external_data_tools external_data_tools = copy_app_model_config_dict.get('external_data_tools', []) for external_data_tool in external_data_tools: if 'enabled' not in external_data_tool or not external_data_tool['enabled']: @@ -366,6 +372,19 @@ class ApplicationManager: config=external_data_tool['config'] ) ) + + # current external_data_tools + for variable in copy_app_model_config_dict.get('user_input_form', []): + typ = list(variable.keys())[0] + if typ == 'external_data_tool': + val = variable[typ] + properties['external_data_variables'].append( + ExternalDataVariableEntity( + variable=val['variable'], + type=val['type'], + config=val['config'] + ) + ) # show retrieve source show_retrieve_source = False @@ -375,15 +394,64 @@ class ApplicationManager: show_retrieve_source = True properties['show_retrieve_source'] = show_retrieve_source + + dataset_ids = [] + if 'datasets' in copy_app_model_config_dict.get('dataset_configs', {}): + datasets = copy_app_model_config_dict.get('dataset_configs', {}).get('datasets', { + 'strategy': 'router', + 'datasets': [] + }) + + + for dataset in datasets.get('datasets', []): + keys = list(dataset.keys()) + if len(keys) == 0 or keys[0] != 'dataset': + continue + dataset = dataset['dataset'] + + if 'enabled' not in dataset or not dataset['enabled']: + continue + + dataset_id = dataset.get('id', None) + if dataset_id: + dataset_ids.append(dataset_id) + else: + datasets = {'strategy': 'router', 'datasets': []} if 'agent_mode' in copy_app_model_config_dict and copy_app_model_config_dict['agent_mode'] \ and 'enabled' in copy_app_model_config_dict['agent_mode'] and copy_app_model_config_dict['agent_mode'][ 'enabled']: - agent_dict = copy_app_model_config_dict.get('agent_mode') - agent_strategy = agent_dict.get('strategy', 'router') - if agent_strategy in ['router', 'react_router']: - dataset_ids = [] - for tool in agent_dict.get('tools', []): + agent_dict = copy_app_model_config_dict.get('agent_mode', {}) + agent_strategy = agent_dict.get('strategy', 'cot') + + if agent_strategy == 'function_call': + strategy = AgentEntity.Strategy.FUNCTION_CALLING + elif agent_strategy == 'cot' or agent_strategy == 'react': + strategy = AgentEntity.Strategy.CHAIN_OF_THOUGHT + else: + # old configs, try to detect default strategy + if copy_app_model_config_dict['model']['provider'] == 'openai': + strategy = AgentEntity.Strategy.FUNCTION_CALLING + else: + strategy = AgentEntity.Strategy.CHAIN_OF_THOUGHT + + agent_tools = [] + for tool in agent_dict.get('tools', []): + keys = tool.keys() + if len(keys) >= 4: + if "enabled" not in tool or not tool["enabled"]: + continue + + agent_tool_properties = { + 'provider_type': tool['provider_type'], + 'provider_id': tool['provider_id'], + 'tool_name': tool['tool_name'], + 'tool_parameters': tool['tool_parameters'] if 'tool_parameters' in tool else {} + } + + agent_tools.append(AgentToolEntity(**agent_tool_properties)) + elif len(keys) == 1: + # old standard key = list(tool.keys())[0] if key != 'dataset': @@ -397,58 +465,57 @@ class ApplicationManager: dataset_id = tool_item['id'] dataset_ids.append(dataset_id) - dataset_configs = copy_app_model_config_dict.get('dataset_configs', {'retrieval_model': 'single'}) - query_variable = copy_app_model_config_dict.get('dataset_query_variable') - if dataset_configs['retrieval_model'] == 'single': - properties['dataset'] = DatasetEntity( - dataset_ids=dataset_ids, - retrieve_config=DatasetRetrieveConfigEntity( - query_variable=query_variable, - retrieve_strategy=DatasetRetrieveConfigEntity.RetrieveStrategy.value_of( - dataset_configs['retrieval_model'] - ), - single_strategy=agent_strategy - ) - ) - else: - properties['dataset'] = DatasetEntity( - dataset_ids=dataset_ids, - retrieve_config=DatasetRetrieveConfigEntity( - query_variable=query_variable, - retrieve_strategy=DatasetRetrieveConfigEntity.RetrieveStrategy.value_of( - dataset_configs['retrieval_model'] - ), - top_k=dataset_configs.get('top_k'), - score_threshold=dataset_configs.get('score_threshold'), - reranking_model=dataset_configs.get('reranking_model') - ) - ) + agent_prompt = agent_dict.get('prompt', None) or {} + # check model mode + model_mode = copy_app_model_config_dict.get('model', {}).get('mode', 'completion') + if model_mode == 'completion': + agent_prompt_entity = AgentPromptEntity( + first_prompt=agent_prompt.get('first_prompt', REACT_PROMPT_TEMPLATES['english']['completion']['prompt']), + next_iteration=agent_prompt.get('next_iteration', REACT_PROMPT_TEMPLATES['english']['completion']['agent_scratchpad']), + ) else: - if agent_strategy == 'react': - strategy = AgentEntity.Strategy.CHAIN_OF_THOUGHT - else: - strategy = AgentEntity.Strategy.FUNCTION_CALLING + agent_prompt_entity = AgentPromptEntity( + first_prompt=agent_prompt.get('first_prompt', REACT_PROMPT_TEMPLATES['english']['chat']['prompt']), + next_iteration=agent_prompt.get('next_iteration', REACT_PROMPT_TEMPLATES['english']['chat']['agent_scratchpad']), + ) - agent_tools = [] - for tool in agent_dict.get('tools', []): - key = list(tool.keys())[0] - tool_item = tool[key] + properties['agent'] = AgentEntity( + provider=properties['model_config'].provider, + model=properties['model_config'].model, + strategy=strategy, + prompt=agent_prompt_entity, + tools=agent_tools, + max_iteration=agent_dict.get('max_iteration', 5) + ) - agent_tool_properties = { - "tool_id": key - } + if len(dataset_ids) > 0: + # dataset configs + dataset_configs = copy_app_model_config_dict.get('dataset_configs', {'retrieval_model': 'single'}) + query_variable = copy_app_model_config_dict.get('dataset_query_variable') - if "enabled" not in tool_item or not tool_item["enabled"]: - continue - - agent_tool_properties["config"] = tool_item - agent_tools.append(AgentToolEntity(**agent_tool_properties)) - - properties['agent'] = AgentEntity( - provider=properties['model_config'].provider, - model=properties['model_config'].model, - strategy=strategy, - tools=agent_tools + if dataset_configs['retrieval_model'] == 'single': + properties['dataset'] = DatasetEntity( + dataset_ids=dataset_ids, + retrieve_config=DatasetRetrieveConfigEntity( + query_variable=query_variable, + retrieve_strategy=DatasetRetrieveConfigEntity.RetrieveStrategy.value_of( + dataset_configs['retrieval_model'] + ), + single_strategy=datasets.get('strategy', 'router') + ) + ) + else: + properties['dataset'] = DatasetEntity( + dataset_ids=dataset_ids, + retrieve_config=DatasetRetrieveConfigEntity( + query_variable=query_variable, + retrieve_strategy=DatasetRetrieveConfigEntity.RetrieveStrategy.value_of( + dataset_configs['retrieval_model'] + ), + top_k=dataset_configs.get('top_k'), + score_threshold=dataset_configs.get('score_threshold'), + reranking_model=dataset_configs.get('reranking_model') + ) ) # file upload @@ -601,6 +668,7 @@ class ApplicationManager: message_id=message.id, type=file.type.value, transfer_method=file.transfer_method.value, + belongs_to='user', url=file.url, upload_file_id=file.upload_file_id, created_by_role=('account' if account_id else 'end_user'), diff --git a/api/core/application_queue_manager.py b/api/core/application_queue_manager.py index 09b92c5f8..605255f3b 100644 --- a/api/core/application_queue_manager.py +++ b/api/core/application_queue_manager.py @@ -7,10 +7,10 @@ from core.entities.application_entities import InvokeFrom from core.entities.queue_entities import (AnnotationReplyEvent, AppQueueEvent, QueueAgentThoughtEvent, QueueErrorEvent, QueueMessage, QueueMessageEndEvent, QueueMessageEvent, QueueMessageReplaceEvent, QueuePingEvent, QueueRetrieverResourcesEvent, - QueueStopEvent) + QueueStopEvent, QueueMessageFileEvent, QueueAgentMessageEvent) from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk from extensions.ext_redis import redis_client -from models.model import MessageAgentThought +from models.model import MessageAgentThought, MessageFile from sqlalchemy.orm import DeclarativeMeta @@ -96,6 +96,18 @@ class ApplicationQueueManager: chunk=chunk ), pub_from) + def publish_agent_chunk_message(self, chunk: LLMResultChunk, pub_from: PublishFrom) -> None: + """ + Publish agent chunk message to channel + + :param chunk: chunk + :param pub_from: publish from + :return: + """ + self.publish(QueueAgentMessageEvent( + chunk=chunk + ), pub_from) + def publish_message_replace(self, text: str, pub_from: PublishFrom) -> None: """ Publish message replace @@ -144,6 +156,17 @@ class ApplicationQueueManager: agent_thought_id=message_agent_thought.id ), pub_from) + def publish_message_file(self, message_file: MessageFile, pub_from: PublishFrom) -> None: + """ + Publish agent thought + :param message_file: message file + :param pub_from: publish from + :return: + """ + self.publish(QueueMessageFileEvent( + message_file_id=message_file.id + ), pub_from) + def publish_error(self, e, pub_from: PublishFrom) -> None: """ Publish error diff --git a/api/core/callback_handler/agent_tool_callback_handler.py b/api/core/callback_handler/agent_tool_callback_handler.py new file mode 100644 index 000000000..c1037035e --- /dev/null +++ b/api/core/callback_handler/agent_tool_callback_handler.py @@ -0,0 +1,74 @@ +import os +from typing import Any, Dict, Optional, Union +from pydantic import BaseModel + +from langchain.callbacks.base import BaseCallbackHandler +from langchain.input import print_text + +class DifyAgentCallbackHandler(BaseCallbackHandler, BaseModel): + """Callback Handler that prints to std out.""" + color: Optional[str] = '' + current_loop = 1 + + def __init__(self, color: Optional[str] = None) -> None: + super().__init__() + """Initialize callback handler.""" + # use a specific color is not specified + self.color = color or 'green' + self.current_loop = 1 + + def on_tool_start( + self, + tool_name: str, + tool_inputs: Dict[str, Any], + ) -> None: + """Do nothing.""" + print_text("\n[on_tool_start] ToolCall:" + tool_name + "\n" + str(tool_inputs) + "\n", color=self.color) + + def on_tool_end( + self, + tool_name: str, + tool_inputs: Dict[str, Any], + tool_outputs: str, + ) -> None: + """If not the final action, print out observation.""" + print_text("\n[on_tool_end]\n", color=self.color) + print_text("Tool: " + tool_name + "\n", color=self.color) + print_text("Inputs: " + str(tool_inputs) + "\n", color=self.color) + print_text("Outputs: " + str(tool_outputs) + "\n", color=self.color) + print_text("\n") + + def on_tool_error( + self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any + ) -> None: + """Do nothing.""" + print_text("\n[on_tool_error] Error: " + str(error) + "\n", color='red') + + def on_agent_start( + self, thought: str + ) -> None: + """Run on agent start.""" + if thought: + print_text("\n[on_agent_start] \nCurrent Loop: " + \ + str(self.current_loop) + \ + "\nThought: " + thought + "\n", color=self.color) + else: + print_text("\n[on_agent_start] \nCurrent Loop: " + str(self.current_loop) + "\n", color=self.color) + + def on_agent_finish( + self, color: Optional[str] = None, **kwargs: Any + ) -> None: + """Run on agent end.""" + print_text("\n[on_agent_finish]\n Loop: " + str(self.current_loop) + "\n", color=self.color) + + self.current_loop += 1 + + @property + def ignore_agent(self) -> bool: + """Whether to ignore agent callbacks.""" + return not os.environ.get("DEBUG") or os.environ.get("DEBUG").lower() != 'true' + + @property + def ignore_chat_model(self) -> bool: + """Whether to ignore chat model callbacks.""" + return not os.environ.get("DEBUG") or os.environ.get("DEBUG").lower() != 'true' diff --git a/api/core/entities/application_entities.py b/api/core/entities/application_entities.py index 47a1ac651..95a9d90f9 100644 --- a/api/core/entities/application_entities.py +++ b/api/core/entities/application_entities.py @@ -1,11 +1,12 @@ from enum import Enum -from typing import Any, Optional, cast +from typing import Optional, Any, cast, Literal, Union + +from pydantic import BaseModel from core.entities.provider_configuration import ProviderModelBundle from core.file.file_obj import FileObj from core.model_runtime.entities.message_entities import PromptMessageRole from core.model_runtime.entities.model_entities import AIModelEntity -from pydantic import BaseModel class ModelConfigEntity(BaseModel): @@ -153,9 +154,35 @@ class AgentToolEntity(BaseModel): """ Agent Tool Entity. """ - tool_id: str - config: dict[str, Any] = {} + provider_type: Literal["builtin", "api"] + provider_id: str + tool_name: str + tool_parameters: dict[str, Any] = {} +class AgentPromptEntity(BaseModel): + """ + Agent Prompt Entity. + """ + first_prompt: str + next_iteration: str + +class AgentScratchpadUnit(BaseModel): + """ + Agent First Prompt Entity. + """ + + class Action(BaseModel): + """ + Action Entity. + """ + action_name: str + action_input: Union[dict, str] + + agent_response: Optional[str] = None + thought: Optional[str] = None + action_str: Optional[str] = None + observation: Optional[str] = None + action: Optional[Action] = None class AgentEntity(BaseModel): """ @@ -171,8 +198,9 @@ class AgentEntity(BaseModel): provider: str model: str strategy: Strategy - tools: list[AgentToolEntity] = [] - + prompt: Optional[AgentPromptEntity] = None + tools: list[AgentToolEntity] = None + max_iteration: int = 5 class AppOrchestrationConfigEntity(BaseModel): """ diff --git a/api/core/entities/queue_entities.py b/api/core/entities/queue_entities.py index 858b00ea6..d6ef28b13 100644 --- a/api/core/entities/queue_entities.py +++ b/api/core/entities/queue_entities.py @@ -10,11 +10,13 @@ class QueueEvent(Enum): QueueEvent enum """ MESSAGE = "message" + AGENT_MESSAGE = "agent_message" MESSAGE_REPLACE = "message-replace" MESSAGE_END = "message-end" RETRIEVER_RESOURCES = "retriever-resources" ANNOTATION_REPLY = "annotation-reply" AGENT_THOUGHT = "agent-thought" + MESSAGE_FILE = "message-file" ERROR = "error" PING = "ping" STOP = "stop" @@ -33,7 +35,14 @@ class QueueMessageEvent(AppQueueEvent): """ event = QueueEvent.MESSAGE chunk: LLMResultChunk - + +class QueueAgentMessageEvent(AppQueueEvent): + """ + QueueMessageEvent entity + """ + event = QueueEvent.AGENT_MESSAGE + chunk: LLMResultChunk + class QueueMessageReplaceEvent(AppQueueEvent): """ @@ -73,7 +82,13 @@ class QueueAgentThoughtEvent(AppQueueEvent): """ event = QueueEvent.AGENT_THOUGHT agent_thought_id: str - + +class QueueMessageFileEvent(AppQueueEvent): + """ + QueueAgentThoughtEvent entity + """ + event = QueueEvent.MESSAGE_FILE + message_file_id: str class QueueErrorEvent(AppQueueEvent): """ diff --git a/api/core/features/agent_runner.py b/api/core/features/agent_runner.py index ba9c3218f..2a7e373db 100644 --- a/api/core/features/agent_runner.py +++ b/api/core/features/agent_runner.py @@ -1,30 +1,27 @@ import logging -from typing import List, Optional, cast +from typing import cast, Optional, List + +from langchain import WikipediaAPIWrapper +from langchain.callbacks.base import BaseCallbackHandler +from langchain.tools import BaseTool, WikipediaQueryRun, Tool +from pydantic import BaseModel, Field from core.agent.agent.agent_llm_callback import AgentLLMCallback -from core.agent.agent_executor import AgentConfiguration, AgentExecutor, PlanningStrategy +from core.agent.agent_executor import PlanningStrategy, AgentConfiguration, AgentExecutor from core.application_queue_manager import ApplicationQueueManager from core.callback_handler.agent_loop_gather_callback_handler import AgentLoopGatherCallbackHandler from core.callback_handler.index_tool_callback_handler import DatasetIndexToolCallbackHandler from core.callback_handler.std_out_callback_handler import DifyStdOutCallbackHandler -from core.entities.application_entities import (AgentEntity, AgentToolEntity, AppOrchestrationConfigEntity, InvokeFrom, - ModelConfigEntity) +from core.entities.application_entities import ModelConfigEntity, InvokeFrom, \ + AgentEntity, AgentToolEntity, AppOrchestrationConfigEntity from core.memory.token_buffer_memory import TokenBufferMemory from core.model_runtime.entities.model_entities import ModelFeature, ModelType from core.model_runtime.model_providers import model_provider_factory from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel -from core.tool.current_datetime_tool import DatetimeTool -from core.tool.dataset_retriever_tool import DatasetRetrieverTool -from core.tool.provider.serpapi_provider import SerpAPIToolProvider -from core.tool.serpapi_wrapper import OptimizedSerpAPIInput, OptimizedSerpAPIWrapper -from core.tool.web_reader_tool import WebReaderTool +from core.tools.tool.dataset_retriever.dataset_retriever_tool import DatasetRetrieverTool from extensions.ext_database import db -from langchain import WikipediaAPIWrapper -from langchain.callbacks.base import BaseCallbackHandler -from langchain.tools import BaseTool, Tool, WikipediaQueryRun from models.dataset import Dataset from models.model import Message -from pydantic import BaseModel, Field logger = logging.getLogger(__name__) @@ -132,55 +129,6 @@ class AgentRunnerFeature: logger.exception("agent_executor run failed") return None - def to_tools(self, tool_configs: list[AgentToolEntity], - invoke_from: InvokeFrom, - callbacks: list[BaseCallbackHandler]) \ - -> Optional[List[BaseTool]]: - """ - Convert tool configs to tools - :param tool_configs: tool configs - :param invoke_from: invoke from - :param callbacks: callbacks - """ - tools = [] - for tool_config in tool_configs: - tool = None - if tool_config.tool_id == "dataset": - tool = self.to_dataset_retriever_tool( - tool_config=tool_config.config, - invoke_from=invoke_from - ) - elif tool_config.tool_id == "web_reader": - tool = self.to_web_reader_tool( - tool_config=tool_config.config, - invoke_from=invoke_from - ) - elif tool_config.tool_id == "google_search": - tool = self.to_google_search_tool( - tool_config=tool_config.config, - invoke_from=invoke_from - ) - elif tool_config.tool_id == "wikipedia": - tool = self.to_wikipedia_tool( - tool_config=tool_config.config, - invoke_from=invoke_from - ) - elif tool_config.tool_id == "current_datetime": - tool = self.to_current_datetime_tool( - tool_config=tool_config.config, - invoke_from=invoke_from - ) - - if tool: - if tool.callbacks is not None: - tool.callbacks.extend(callbacks) - else: - tool.callbacks = callbacks - - tools.append(tool) - - return tools - def to_dataset_retriever_tool(self, tool_config: dict, invoke_from: InvokeFrom) \ -> Optional[BaseTool]: @@ -247,78 +195,4 @@ class AgentRunnerFeature: retriever_from=invoke_from.to_source() ) - return tool - - def to_web_reader_tool(self, tool_config: dict, - invoke_from: InvokeFrom) -> Optional[BaseTool]: - """ - A tool for reading web pages - :param tool_config: tool config - :param invoke_from: invoke from - :return: - """ - model_parameters = { - "temperature": 0, - "max_tokens": 500 - } - - tool = WebReaderTool( - model_config=self.model_config, - model_parameters=model_parameters, - max_chunk_length=4000, - continue_reading=True - ) - - return tool - - def to_google_search_tool(self, tool_config: dict, - invoke_from: InvokeFrom) -> Optional[BaseTool]: - """ - A tool for performing a Google search and extracting snippets and webpages - :param tool_config: tool config - :param invoke_from: invoke from - :return: - """ - tool_provider = SerpAPIToolProvider(tenant_id=self.tenant_id) - func_kwargs = tool_provider.credentials_to_func_kwargs() - if not func_kwargs: - return None - - tool = Tool( - name="google_search", - description="A tool for performing a Google search and extracting snippets and webpages " - "when you need to search for something you don't know or when your information " - "is not up to date. " - "Input should be a search query.", - func=OptimizedSerpAPIWrapper(**func_kwargs).run, - args_schema=OptimizedSerpAPIInput - ) - - return tool - - def to_current_datetime_tool(self, tool_config: dict, - invoke_from: InvokeFrom) -> Optional[BaseTool]: - """ - A tool for getting the current date and time - :param tool_config: tool config - :param invoke_from: invoke from - :return: - """ - return DatetimeTool() - - def to_wikipedia_tool(self, tool_config: dict, - invoke_from: InvokeFrom) -> Optional[BaseTool]: - """ - A tool for searching Wikipedia - :param tool_config: tool config - :param invoke_from: invoke from - :return: - """ - class WikipediaInput(BaseModel): - query: str = Field(..., description="search query.") - - return WikipediaQueryRun( - name="wikipedia", - api_wrapper=WikipediaAPIWrapper(doc_content_chars_max=4000), - args_schema=WikipediaInput - ) + return tool \ No newline at end of file diff --git a/api/core/features/assistant_base_runner.py b/api/core/features/assistant_base_runner.py new file mode 100644 index 000000000..2a896d6fb --- /dev/null +++ b/api/core/features/assistant_base_runner.py @@ -0,0 +1,558 @@ +import logging +import json + +from typing import Optional, List, Tuple, Union +from datetime import datetime +from mimetypes import guess_extension + +from core.app_runner.app_runner import AppRunner +from extensions.ext_database import db + +from models.model import MessageAgentThought, Message, MessageFile +from models.tools import ToolConversationVariables + +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolInvokeMessageBinary, \ + ToolRuntimeVariablePool, ToolParamter +from core.tools.tool.tool import Tool +from core.tools.tool_manager import ToolManager +from core.tools.tool_file_manager import ToolFileManager +from core.tools.tool.dataset_retriever_tool import DatasetRetrieverTool +from core.app_runner.app_runner import AppRunner +from core.callback_handler.agent_tool_callback_handler import DifyAgentCallbackHandler +from core.callback_handler.index_tool_callback_handler import DatasetIndexToolCallbackHandler +from core.entities.application_entities import ModelConfigEntity, AgentEntity, AgentToolEntity +from core.application_queue_manager import ApplicationQueueManager +from core.memory.token_buffer_memory import TokenBufferMemory +from core.entities.application_entities import ModelConfigEntity, \ + AgentEntity, AppOrchestrationConfigEntity, ApplicationGenerateEntity, InvokeFrom +from core.model_runtime.entities.message_entities import PromptMessage, PromptMessageTool +from core.model_runtime.entities.llm_entities import LLMUsage +from core.model_runtime.utils.encoders import jsonable_encoder +from core.file.message_file_parser import FileTransferMethod + +logger = logging.getLogger(__name__) + +class BaseAssistantApplicationRunner(AppRunner): + def __init__(self, tenant_id: str, + application_generate_entity: ApplicationGenerateEntity, + app_orchestration_config: AppOrchestrationConfigEntity, + model_config: ModelConfigEntity, + config: AgentEntity, + queue_manager: ApplicationQueueManager, + message: Message, + user_id: str, + memory: Optional[TokenBufferMemory] = None, + prompt_messages: Optional[List[PromptMessage]] = None, + variables_pool: Optional[ToolRuntimeVariablePool] = None, + db_variables: Optional[ToolConversationVariables] = None, + ) -> None: + """ + Agent runner + :param tenant_id: tenant id + :param app_orchestration_config: app orchestration config + :param model_config: model config + :param config: dataset config + :param queue_manager: queue manager + :param message: message + :param user_id: user id + :param agent_llm_callback: agent llm callback + :param callback: callback + :param memory: memory + """ + self.tenant_id = tenant_id + self.application_generate_entity = application_generate_entity + self.app_orchestration_config = app_orchestration_config + self.model_config = model_config + self.config = config + self.queue_manager = queue_manager + self.message = message + self.user_id = user_id + self.memory = memory + self.history_prompt_messages = prompt_messages + self.variables_pool = variables_pool + self.db_variables_pool = db_variables + + # init callback + self.agent_callback = DifyAgentCallbackHandler() + # init dataset tools + hit_callback = DatasetIndexToolCallbackHandler( + queue_manager=queue_manager, + app_id=self.application_generate_entity.app_id, + message_id=message.id, + user_id=user_id, + invoke_from=self.application_generate_entity.invoke_from, + ) + self.dataset_tools = DatasetRetrieverTool.get_dataset_tools( + tenant_id=tenant_id, + dataset_ids=app_orchestration_config.dataset.dataset_ids if app_orchestration_config.dataset else [], + retrieve_config=app_orchestration_config.dataset.retrieve_config if app_orchestration_config.dataset else None, + return_resource=app_orchestration_config.show_retrieve_source, + invoke_from=application_generate_entity.invoke_from, + hit_callback=hit_callback + ) + # get how many agent thoughts have been created + self.agent_thought_count = db.session.query(MessageAgentThought).filter( + MessageAgentThought.message_id == self.message.id, + ).count() + + def _repacket_app_orchestration_config(self, app_orchestration_config: AppOrchestrationConfigEntity) -> AppOrchestrationConfigEntity: + """ + Repacket app orchestration config + """ + if app_orchestration_config.prompt_template.simple_prompt_template is None: + app_orchestration_config.prompt_template.simple_prompt_template = '' + + return app_orchestration_config + + def _convert_tool_response_to_str(self, tool_response: List[ToolInvokeMessage]) -> str: + """ + Handle tool response + """ + result = '' + for response in tool_response: + if response.type == ToolInvokeMessage.MessageType.TEXT: + result += response.message + elif response.type == ToolInvokeMessage.MessageType.LINK: + result += f"result link: {response.message}. please dirct user to check it." + elif response.type == ToolInvokeMessage.MessageType.IMAGE_LINK or \ + response.type == ToolInvokeMessage.MessageType.IMAGE: + result += f"image has been created and sent to user already, you should tell user to check it now." + else: + result += f"tool response: {response.message}." + + return result + + def _convert_tool_to_prompt_message_tool(self, tool: AgentToolEntity) -> Tuple[PromptMessageTool, Tool]: + """ + convert tool to prompt message tool + """ + tool_entity = ToolManager.get_tool_runtime( + provider_type=tool.provider_type, provider_name=tool.provider_id, tool_name=tool.tool_name, + tanent_id=self.application_generate_entity.tenant_id, + agent_callback=self.agent_callback + ) + tool_entity.load_variables(self.variables_pool) + + message_tool = PromptMessageTool( + name=tool.tool_name, + description=tool_entity.description.llm, + parameters={ + "type": "object", + "properties": {}, + "required": [], + } + ) + + runtime_parameters = {} + + parameters = tool_entity.parameters or [] + user_parameters = tool_entity.get_runtime_parameters() or [] + + # override parameters + for parameter in user_parameters: + # check if parameter in tool parameters + found = False + for tool_parameter in parameters: + if tool_parameter.name == parameter.name: + found = True + break + + if found: + # override parameter + tool_parameter.type = parameter.type + tool_parameter.form = parameter.form + tool_parameter.required = parameter.required + tool_parameter.default = parameter.default + tool_parameter.options = parameter.options + tool_parameter.llm_description = parameter.llm_description + else: + # add new parameter + parameters.append(parameter) + + for parameter in parameters: + parameter_type = 'string' + enum = [] + if parameter.type == ToolParamter.ToolParameterType.STRING: + parameter_type = 'string' + elif parameter.type == ToolParamter.ToolParameterType.BOOLEAN: + parameter_type = 'boolean' + elif parameter.type == ToolParamter.ToolParameterType.NUMBER: + parameter_type = 'number' + elif parameter.type == ToolParamter.ToolParameterType.SELECT: + for option in parameter.options: + enum.append(option.value) + parameter_type = 'string' + else: + raise ValueError(f"parameter type {parameter.type} is not supported") + + if parameter.form == ToolParamter.ToolParameterForm.FORM: + # get tool parameter from form + tool_parameter_config = tool.tool_parameters.get(parameter.name) + if not tool_parameter_config: + # get default value + tool_parameter_config = parameter.default + if not tool_parameter_config and parameter.required: + raise ValueError(f"tool parameter {parameter.name} not found in tool config") + + if parameter.type == ToolParamter.ToolParameterType.SELECT: + # check if tool_parameter_config in options + options = list(map(lambda x: x.value, parameter.options)) + if tool_parameter_config not in options: + raise ValueError(f"tool parameter {parameter.name} value {tool_parameter_config} not in options {options}") + + # convert tool parameter config to correct type + try: + if parameter.type == ToolParamter.ToolParameterType.NUMBER: + # check if tool parameter is integer + if isinstance(tool_parameter_config, int): + tool_parameter_config = tool_parameter_config + elif isinstance(tool_parameter_config, float): + tool_parameter_config = tool_parameter_config + elif isinstance(tool_parameter_config, str): + if '.' in tool_parameter_config: + tool_parameter_config = float(tool_parameter_config) + else: + tool_parameter_config = int(tool_parameter_config) + elif parameter.type == ToolParamter.ToolParameterType.BOOLEAN: + tool_parameter_config = bool(tool_parameter_config) + elif parameter.type not in [ToolParamter.ToolParameterType.SELECT, ToolParamter.ToolParameterType.STRING]: + tool_parameter_config = str(tool_parameter_config) + elif parameter.type == ToolParamter.ToolParameterType: + tool_parameter_config = str(tool_parameter_config) + except Exception as e: + raise ValueError(f"tool parameter {parameter.name} value {tool_parameter_config} is not correct type") + + # save tool parameter to tool entity memory + runtime_parameters[parameter.name] = tool_parameter_config + + elif parameter.form == ToolParamter.ToolParameterForm.LLM: + message_tool.parameters['properties'][parameter.name] = { + "type": parameter_type, + "description": parameter.llm_description or '', + } + + if len(enum) > 0: + message_tool.parameters['properties'][parameter.name]['enum'] = enum + + if parameter.required: + message_tool.parameters['required'].append(parameter.name) + + tool_entity.runtime.runtime_parameters.update(runtime_parameters) + + return message_tool, tool_entity + + def _convert_dataset_retriever_tool_to_prompt_message_tool(self, tool: DatasetRetrieverTool) -> PromptMessageTool: + """ + convert dataset retriever tool to prompt message tool + """ + prompt_tool = PromptMessageTool( + name=tool.identity.name, + description=tool.description.llm, + parameters={ + "type": "object", + "properties": {}, + "required": [], + } + ) + + for parameter in tool.get_runtime_parameters(): + parameter_type = 'string' + + prompt_tool.parameters['properties'][parameter.name] = { + "type": parameter_type, + "description": parameter.llm_description or '', + } + + if parameter.required: + if parameter.name not in prompt_tool.parameters['required']: + prompt_tool.parameters['required'].append(parameter.name) + + return prompt_tool + + def update_prompt_message_tool(self, tool: Tool, prompt_tool: PromptMessageTool) -> PromptMessageTool: + """ + update prompt message tool + """ + # try to get tool runtime parameters + tool_runtime_parameters = tool.get_runtime_parameters() or [] + + for parameter in tool_runtime_parameters: + parameter_type = 'string' + enum = [] + if parameter.type == ToolParamter.ToolParameterType.STRING: + parameter_type = 'string' + elif parameter.type == ToolParamter.ToolParameterType.BOOLEAN: + parameter_type = 'boolean' + elif parameter.type == ToolParamter.ToolParameterType.NUMBER: + parameter_type = 'number' + elif parameter.type == ToolParamter.ToolParameterType.SELECT: + for option in parameter.options: + enum.append(option.value) + parameter_type = 'string' + else: + raise ValueError(f"parameter type {parameter.type} is not supported") + + if parameter.form == ToolParamter.ToolParameterForm.LLM: + prompt_tool.parameters['properties'][parameter.name] = { + "type": parameter_type, + "description": parameter.llm_description or '', + } + + if len(enum) > 0: + prompt_tool.parameters['properties'][parameter.name]['enum'] = enum + + if parameter.required: + if parameter.name not in prompt_tool.parameters['required']: + prompt_tool.parameters['required'].append(parameter.name) + + return prompt_tool + + def extract_tool_response_binary(self, tool_response: List[ToolInvokeMessage]) -> List[ToolInvokeMessageBinary]: + """ + Extract tool response binary + """ + result = [] + + for response in tool_response: + if response.type == ToolInvokeMessage.MessageType.IMAGE_LINK or \ + response.type == ToolInvokeMessage.MessageType.IMAGE: + result.append(ToolInvokeMessageBinary( + mimetype=response.meta.get('mime_type', 'octet/stream'), + url=response.message, + save_as=response.save_as, + )) + elif response.type == ToolInvokeMessage.MessageType.BLOB: + result.append(ToolInvokeMessageBinary( + mimetype=response.meta.get('mime_type', 'octet/stream'), + url=response.message, + save_as=response.save_as, + )) + elif response.type == ToolInvokeMessage.MessageType.LINK: + # check if there is a mime type in meta + if response.meta and 'mime_type' in response.meta: + result.append(ToolInvokeMessageBinary( + mimetype=response.meta.get('mime_type', 'octet/stream') if response.meta else 'octet/stream', + url=response.message, + save_as=response.save_as, + )) + + return result + + def create_message_files(self, messages: List[ToolInvokeMessageBinary]) -> List[Tuple[MessageFile, bool]]: + """ + Create message file + + :param messages: messages + :return: message files, should save as variable + """ + result = [] + + for message in messages: + file_type = 'bin' + if 'image' in message.mimetype: + file_type = 'image' + elif 'video' in message.mimetype: + file_type = 'video' + elif 'audio' in message.mimetype: + file_type = 'audio' + elif 'text' in message.mimetype: + file_type = 'text' + elif 'pdf' in message.mimetype: + file_type = 'pdf' + elif 'zip' in message.mimetype: + file_type = 'archive' + # ... + + invoke_from = self.application_generate_entity.invoke_from + + message_file = MessageFile( + message_id=self.message.id, + type=file_type, + transfer_method=FileTransferMethod.TOOL_FILE.value, + belongs_to='assistant', + url=message.url, + upload_file_id=None, + created_by_role=('account'if invoke_from in [InvokeFrom.EXPLORE, InvokeFrom.DEBUGGER] else 'end_user'), + created_by=self.user_id, + ) + db.session.add(message_file) + result.append(( + message_file, + message.save_as + )) + + db.session.commit() + + return result + + def create_agent_thought(self, message_id: str, message: str, + tool_name: str, tool_input: str, messages_ids: List[str] + ) -> MessageAgentThought: + """ + Create agent thought + """ + thought = MessageAgentThought( + message_id=message_id, + message_chain_id=None, + thought='', + tool=tool_name, + tool_input=tool_input, + message=message, + message_token=0, + message_unit_price=0, + message_price_unit=0, + message_files=json.dumps(messages_ids) if messages_ids else '', + answer='', + observation='', + answer_token=0, + answer_unit_price=0, + answer_price_unit=0, + tokens=0, + total_price=0, + position=self.agent_thought_count + 1, + currency='USD', + latency=0, + created_by_role='account', + created_by=self.user_id, + ) + + db.session.add(thought) + db.session.commit() + + self.agent_thought_count += 1 + + return thought + + def save_agent_thought(self, + agent_thought: MessageAgentThought, + tool_name: str, + tool_input: Union[str, dict], + thought: str, + observation: str, + answer: str, + messages_ids: List[str], + llm_usage: LLMUsage = None) -> MessageAgentThought: + """ + Save agent thought + """ + if thought is not None: + agent_thought.thought = thought + + if tool_name is not None: + agent_thought.tool = tool_name + + if tool_input is not None: + if isinstance(tool_input, dict): + try: + tool_input = json.dumps(tool_input, ensure_ascii=False) + except Exception as e: + tool_input = json.dumps(tool_input) + + agent_thought.tool_input = tool_input + + if observation is not None: + agent_thought.observation = observation + + if answer is not None: + agent_thought.answer = answer + + if messages_ids is not None and len(messages_ids) > 0: + agent_thought.message_files = json.dumps(messages_ids) + + if llm_usage: + agent_thought.message_token = llm_usage.prompt_tokens + agent_thought.message_price_unit = llm_usage.prompt_price_unit + agent_thought.message_unit_price = llm_usage.prompt_unit_price + agent_thought.answer_token = llm_usage.completion_tokens + agent_thought.answer_price_unit = llm_usage.completion_price_unit + agent_thought.answer_unit_price = llm_usage.completion_unit_price + agent_thought.tokens = llm_usage.total_tokens + agent_thought.total_price = llm_usage.total_price + + db.session.commit() + + def get_history_prompt_messages(self) -> List[PromptMessage]: + """ + Get history prompt messages + """ + if self.history_prompt_messages is None: + self.history_prompt_messages = db.session.query(PromptMessage).filter( + PromptMessage.message_id == self.message.id, + ).order_by(PromptMessage.position.asc()).all() + + return self.history_prompt_messages + + def transform_tool_invoke_messages(self, messages: List[ToolInvokeMessage]) -> List[ToolInvokeMessage]: + """ + Transform tool message into agent thought + """ + result = [] + + for message in messages: + if message.type == ToolInvokeMessage.MessageType.TEXT: + result.append(message) + elif message.type == ToolInvokeMessage.MessageType.LINK: + result.append(message) + elif message.type == ToolInvokeMessage.MessageType.IMAGE: + # try to download image + try: + file = ToolFileManager.create_file_by_url(user_id=self.user_id, tenant_id=self.tenant_id, + conversation_id=self.message.conversation_id, + file_url=message.message) + + url = f'/files/tools/{file.id}{guess_extension(file.mimetype) or ".png"}' + + result.append(ToolInvokeMessage( + type=ToolInvokeMessage.MessageType.IMAGE_LINK, + message=url, + save_as=message.save_as, + meta=message.meta.copy() if message.meta is not None else {}, + )) + except Exception as e: + logger.exception(e) + result.append(ToolInvokeMessage( + type=ToolInvokeMessage.MessageType.TEXT, + message=f"Failed to download image: {message.message}, you can try to download it yourself.", + meta=message.meta.copy() if message.meta is not None else {}, + save_as=message.save_as, + )) + elif message.type == ToolInvokeMessage.MessageType.BLOB: + # get mime type and save blob to storage + mimetype = message.meta.get('mime_type', 'octet/stream') + # if message is str, encode it to bytes + if isinstance(message.message, str): + message.message = message.message.encode('utf-8') + file = ToolFileManager.create_file_by_raw(user_id=self.user_id, tenant_id=self.tenant_id, + conversation_id=self.message.conversation_id, + file_binary=message.message, + mimetype=mimetype) + + url = f'/files/tools/{file.id}{guess_extension(file.mimetype) or ".bin"}' + + # check if file is image + if 'image' in mimetype: + result.append(ToolInvokeMessage( + type=ToolInvokeMessage.MessageType.IMAGE_LINK, + message=url, + save_as=message.save_as, + meta=message.meta.copy() if message.meta is not None else {}, + )) + else: + result.append(ToolInvokeMessage( + type=ToolInvokeMessage.MessageType.LINK, + message=url, + save_as=message.save_as, + meta=message.meta.copy() if message.meta is not None else {}, + )) + else: + result.append(message) + + return result + + def update_db_variables(self, tool_variables: ToolRuntimeVariablePool, db_variables: ToolConversationVariables): + """ + convert tool variables to db variables + """ + db_variables.updated_at = datetime.utcnow() + db_variables.variables_str = json.dumps(jsonable_encoder(tool_variables.pool)) + db.session.commit() \ No newline at end of file diff --git a/api/core/features/assistant_cot_runner.py b/api/core/features/assistant_cot_runner.py new file mode 100644 index 000000000..130833c7b --- /dev/null +++ b/api/core/features/assistant_cot_runner.py @@ -0,0 +1,578 @@ +import json +import logging +import re +from typing import Literal, Union, Generator, Dict, List + +from core.entities.application_entities import AgentPromptEntity, AgentScratchpadUnit +from core.application_queue_manager import PublishFrom +from core.model_runtime.utils.encoders import jsonable_encoder +from core.model_runtime.entities.message_entities import PromptMessageTool, PromptMessage, \ + UserPromptMessage, SystemPromptMessage, AssistantPromptMessage +from core.model_runtime.entities.llm_entities import LLMResult, LLMUsage, LLMResultChunk, LLMResultChunkDelta +from core.model_manager import ModelInstance + +from core.tools.errors import ToolInvokeError, ToolNotFoundError, \ + ToolNotSupportedError, ToolProviderNotFoundError, ToolParamterValidationError, \ + ToolProviderCredentialValidationError + +from core.features.assistant_base_runner import BaseAssistantApplicationRunner + +from models.model import Conversation, Message + +logger = logging.getLogger(__name__) + +class AssistantCotApplicationRunner(BaseAssistantApplicationRunner): + def run(self, model_instance: ModelInstance, + conversation: Conversation, + message: Message, + query: str, + ) -> Union[Generator, LLMResult]: + """ + Run Cot agent application + """ + app_orchestration_config = self.app_orchestration_config + self._repacket_app_orchestration_config(app_orchestration_config) + + agent_scratchpad: List[AgentScratchpadUnit] = [] + + # check model mode + if self.app_orchestration_config.model_config.mode == "completion": + # TODO: stop words + if 'Observation' not in app_orchestration_config.model_config.stop: + app_orchestration_config.model_config.stop.append('Observation') + + iteration_step = 1 + max_iteration_steps = min(self.app_orchestration_config.agent.max_iteration, 5) + 1 + + prompt_messages = self.history_prompt_messages + + # convert tools into ModelRuntime Tool format + prompt_messages_tools: List[PromptMessageTool] = [] + tool_instances = {} + for tool in self.app_orchestration_config.agent.tools if self.app_orchestration_config.agent else []: + try: + prompt_tool, tool_entity = self._convert_tool_to_prompt_message_tool(tool) + except Exception: + # api tool may be deleted + continue + # save tool entity + tool_instances[tool.tool_name] = tool_entity + # save prompt tool + prompt_messages_tools.append(prompt_tool) + + # convert dataset tools into ModelRuntime Tool format + for dataset_tool in self.dataset_tools: + prompt_tool = self._convert_dataset_retriever_tool_to_prompt_message_tool(dataset_tool) + # save prompt tool + prompt_messages_tools.append(prompt_tool) + # save tool entity + tool_instances[dataset_tool.identity.name] = dataset_tool + + function_call_state = True + llm_usage = { + 'usage': None + } + final_answer = '' + + def increse_usage(final_llm_usage_dict: Dict[str, LLMUsage], usage: LLMUsage): + if not final_llm_usage_dict['usage']: + final_llm_usage_dict['usage'] = usage + else: + llm_usage = final_llm_usage_dict['usage'] + llm_usage.prompt_tokens += usage.prompt_tokens + llm_usage.completion_tokens += usage.completion_tokens + llm_usage.prompt_price += usage.prompt_price + llm_usage.completion_price += usage.completion_price + + while function_call_state and iteration_step <= max_iteration_steps: + # continue to run until there is not any tool call + function_call_state = False + + if iteration_step == max_iteration_steps: + # the last iteration, remove all tools + prompt_messages_tools = [] + + message_file_ids = [] + agent_thought = self.create_agent_thought( + message_id=message.id, + message='', + tool_name='', + tool_input='', + messages_ids=message_file_ids + ) + self.queue_manager.publish_agent_thought(agent_thought, PublishFrom.APPLICATION_MANAGER) + + # update prompt messages + prompt_messages = self._originze_cot_prompt_messages( + mode=app_orchestration_config.model_config.mode, + prompt_messages=prompt_messages, + tools=prompt_messages_tools, + agent_scratchpad=agent_scratchpad, + agent_prompt_message=app_orchestration_config.agent.prompt, + instruction=app_orchestration_config.prompt_template.simple_prompt_template, + input=query + ) + + # recale llm max tokens + self.recale_llm_max_tokens(self.model_config, prompt_messages) + # invoke model + llm_result: LLMResult = model_instance.invoke_llm( + prompt_messages=prompt_messages, + model_parameters=app_orchestration_config.model_config.parameters, + tools=[], + stop=app_orchestration_config.model_config.stop, + stream=False, + user=self.user_id, + callbacks=[], + ) + + # check llm result + if not llm_result: + raise ValueError("failed to invoke llm") + + # get scratchpad + scratchpad = self._extract_response_scratchpad(llm_result.message.content) + agent_scratchpad.append(scratchpad) + + # get llm usage + if llm_result.usage: + increse_usage(llm_usage, llm_result.usage) + + self.save_agent_thought(agent_thought=agent_thought, + tool_name=scratchpad.action.action_name if scratchpad.action else '', + tool_input=scratchpad.action.action_input if scratchpad.action else '', + thought=scratchpad.thought, + observation='', + answer=llm_result.message.content, + messages_ids=[], + llm_usage=llm_result.usage) + + if scratchpad.action and scratchpad.action.action_name.lower() != "final answer": + self.queue_manager.publish_agent_thought(agent_thought, PublishFrom.APPLICATION_MANAGER) + + # publish agent thought if it's not empty and there is a action + if scratchpad.thought and scratchpad.action: + # check if final answer + if not scratchpad.action.action_name.lower() == "final answer": + yield LLMResultChunk( + model=model_instance.model, + prompt_messages=prompt_messages, + delta=LLMResultChunkDelta( + index=0, + message=AssistantPromptMessage( + content=scratchpad.thought + ), + usage=llm_result.usage, + ), + system_fingerprint='' + ) + + if not scratchpad.action: + # failed to extract action, return final answer directly + final_answer = scratchpad.agent_response or '' + else: + if scratchpad.action.action_name.lower() == "final answer": + # action is final answer, return final answer directly + try: + final_answer = scratchpad.action.action_input if \ + isinstance(scratchpad.action.action_input, str) else \ + json.dumps(scratchpad.action.action_input) + except json.JSONDecodeError: + final_answer = f'{scratchpad.action.action_input}' + else: + function_call_state = True + + # action is tool call, invoke tool + tool_call_name = scratchpad.action.action_name + tool_call_args = scratchpad.action.action_input + tool_instance = tool_instances.get(tool_call_name) + if not tool_instance: + logger.error(f"failed to find tool instance: {tool_call_name}") + answer = f"there is not a tool named {tool_call_name}" + self.save_agent_thought(agent_thought=agent_thought, + tool_name='', + tool_input='', + thought=None, + observation=answer, + answer=answer, + messages_ids=[]) + self.queue_manager.publish_agent_thought(agent_thought, PublishFrom.APPLICATION_MANAGER) + else: + # invoke tool + error_response = None + try: + tool_response = tool_instance.invoke( + user_id=self.user_id, + tool_paramters=tool_call_args if isinstance(tool_call_args, dict) else json.loads(tool_call_args) + ) + # transform tool response to llm friendly response + tool_response = self.transform_tool_invoke_messages(tool_response) + # extract binary data from tool invoke message + binary_files = self.extract_tool_response_binary(tool_response) + # create message file + message_files = self.create_message_files(binary_files) + # publish files + for message_file, save_as in message_files: + if save_as: + self.variables_pool.set_file(tool_name=tool_call_name, + value=message_file.id, + name=save_as) + self.queue_manager.publish_message_file(message_file, PublishFrom.APPLICATION_MANAGER) + + message_file_ids = [message_file.id for message_file, _ in message_files] + except ToolProviderCredentialValidationError as e: + error_response = f"Plese check your tool provider credentials" + except ( + ToolNotFoundError, ToolNotSupportedError, ToolProviderNotFoundError + ) as e: + error_response = f"there is not a tool named {tool_call_name}" + except ( + ToolParamterValidationError + ) as e: + error_response = f"tool paramters validation error: {e}, please check your tool paramters" + except ToolInvokeError as e: + error_response = f"tool invoke error: {e}" + except Exception as e: + error_response = f"unknown error: {e}" + + if error_response: + observation = error_response + logger.error(error_response) + else: + observation = self._convert_tool_response_to_str(tool_response) + + # save scratchpad + scratchpad.observation = observation + scratchpad.agent_response = llm_result.message.content + + # save agent thought + self.save_agent_thought( + agent_thought=agent_thought, + tool_name=tool_call_name, + tool_input=tool_call_args, + thought=None, + observation=observation, + answer=llm_result.message.content, + messages_ids=message_file_ids, + ) + self.queue_manager.publish_agent_thought(agent_thought, PublishFrom.APPLICATION_MANAGER) + + # update prompt tool message + for prompt_tool in prompt_messages_tools: + self.update_prompt_message_tool(tool_instances[prompt_tool.name], prompt_tool) + + iteration_step += 1 + + yield LLMResultChunk( + model=model_instance.model, + prompt_messages=prompt_messages, + delta=LLMResultChunkDelta( + index=0, + message=AssistantPromptMessage( + content=final_answer + ), + usage=llm_usage['usage'] + ), + system_fingerprint='' + ) + + # save agent thought + self.save_agent_thought( + agent_thought=agent_thought, + tool_name='', + tool_input='', + thought=final_answer, + observation='', + answer=final_answer, + messages_ids=[] + ) + + self.update_db_variables(self.variables_pool, self.db_variables_pool) + # publish end event + self.queue_manager.publish_message_end(LLMResult( + model=model_instance.model, + prompt_messages=prompt_messages, + message=AssistantPromptMessage( + content=final_answer + ), + usage=llm_usage['usage'], + system_fingerprint='' + ), PublishFrom.APPLICATION_MANAGER) + + def _extract_response_scratchpad(self, content: str) -> AgentScratchpadUnit: + """ + extract response from llm response + """ + def extra_quotes() -> AgentScratchpadUnit: + agent_response = content + # try to extract all quotes + pattern = re.compile(r'```(.*?)```', re.DOTALL) + quotes = pattern.findall(content) + + # try to extract action from end to start + for i in range(len(quotes) - 1, 0, -1): + """ + 1. use json load to parse action + 2. use plain text `Action: xxx` to parse action + """ + try: + action = json.loads(quotes[i].replace('```', '')) + action_name = action.get("action") + action_input = action.get("action_input") + agent_thought = agent_response.replace(quotes[i], '') + + if action_name and action_input: + return AgentScratchpadUnit( + agent_response=content, + thought=agent_thought, + action_str=quotes[i], + action=AgentScratchpadUnit.Action( + action_name=action_name, + action_input=action_input, + ) + ) + except: + # try to parse action from plain text + action_name = re.findall(r'action: (.*)', quotes[i], re.IGNORECASE) + action_input = re.findall(r'action input: (.*)', quotes[i], re.IGNORECASE) + # delete action from agent response + agent_thought = agent_response.replace(quotes[i], '') + # remove extra quotes + agent_thought = re.sub(r'```(json)*\n*```', '', agent_thought, flags=re.DOTALL) + # remove Action: xxx from agent thought + agent_thought = re.sub(r'Action:.*', '', agent_thought, flags=re.IGNORECASE) + + if action_name and action_input: + return AgentScratchpadUnit( + agent_response=content, + thought=agent_thought, + action_str=quotes[i], + action=AgentScratchpadUnit.Action( + action_name=action_name[0], + action_input=action_input[0], + ) + ) + + def extra_json(): + agent_response = content + # try to extract all json + structures, pair_match_stack = [], [] + started_at, end_at = 0, 0 + for i in range(len(content)): + if content[i] == '{': + pair_match_stack.append(i) + if len(pair_match_stack) == 1: + started_at = i + elif content[i] == '}': + begin = pair_match_stack.pop() + if not pair_match_stack: + end_at = i + 1 + structures.append((content[begin:i+1], (started_at, end_at))) + + # handle the last character + if pair_match_stack: + end_at = len(content) + structures.append((content[pair_match_stack[0]:], (started_at, end_at))) + + for i in range(len(structures), 0, -1): + try: + json_content, (started_at, end_at) = structures[i - 1] + action = json.loads(json_content) + action_name = action.get("action") + action_input = action.get("action_input") + # delete json content from agent response + agent_thought = agent_response[:started_at] + agent_response[end_at:] + # remove extra quotes like ```(json)*\n\n``` + agent_thought = re.sub(r'```(json)*\n*```', '', agent_thought, flags=re.DOTALL) + # remove Action: xxx from agent thought + agent_thought = re.sub(r'Action:.*', '', agent_thought, flags=re.IGNORECASE) + + if action_name and action_input: + return AgentScratchpadUnit( + agent_response=content, + thought=agent_thought, + action_str=json_content, + action=AgentScratchpadUnit.Action( + action_name=action_name, + action_input=action_input, + ) + ) + except: + pass + + agent_scratchpad = extra_quotes() + if agent_scratchpad: + return agent_scratchpad + agent_scratchpad = extra_json() + if agent_scratchpad: + return agent_scratchpad + + return AgentScratchpadUnit( + agent_response=content, + thought=content, + action_str='', + action=None + ) + + def _check_cot_prompt_messages(self, mode: Literal["completion", "chat"], + agent_prompt_message: AgentPromptEntity, + ): + """ + check chain of thought prompt messages, a standard prompt message is like: + Respond to the human as helpfully and accurately as possible. + + {{instruction}} + + You have access to the following tools: + + {{tools}} + + Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input). + Valid action values: "Final Answer" or {{tool_names}} + + Provide only ONE action per $JSON_BLOB, as shown: + + ``` + { + "action": $TOOL_NAME, + "action_input": $ACTION_INPUT + } + ``` + """ + + # parse agent prompt message + first_prompt = agent_prompt_message.first_prompt + next_iteration = agent_prompt_message.next_iteration + + if not isinstance(first_prompt, str) or not isinstance(next_iteration, str): + raise ValueError(f"first_prompt or next_iteration is required in CoT agent mode") + + # check instruction, tools, and tool_names slots + if not first_prompt.find("{{instruction}}") >= 0: + raise ValueError("{{instruction}} is required in first_prompt") + if not first_prompt.find("{{tools}}") >= 0: + raise ValueError("{{tools}} is required in first_prompt") + if not first_prompt.find("{{tool_names}}") >= 0: + raise ValueError("{{tool_names}} is required in first_prompt") + + if mode == "completion": + if not first_prompt.find("{{query}}") >= 0: + raise ValueError("{{query}} is required in first_prompt") + if not first_prompt.find("{{agent_scratchpad}}") >= 0: + raise ValueError("{{agent_scratchpad}} is required in first_prompt") + + if mode == "completion": + if not next_iteration.find("{{observation}}") >= 0: + raise ValueError("{{observation}} is required in next_iteration") + + def _convert_strachpad_list_to_str(self, agent_scratchpad: List[AgentScratchpadUnit]) -> str: + """ + convert agent scratchpad list to str + """ + next_iteration = self.app_orchestration_config.agent.prompt.next_iteration + + result = '' + for scratchpad in agent_scratchpad: + result += scratchpad.thought + next_iteration.replace("{{observation}}", scratchpad.observation) + "\n" + + return result + + def _originze_cot_prompt_messages(self, mode: Literal["completion", "chat"], + prompt_messages: List[PromptMessage], + tools: List[PromptMessageTool], + agent_scratchpad: List[AgentScratchpadUnit], + agent_prompt_message: AgentPromptEntity, + instruction: str, + input: str, + ) -> List[PromptMessage]: + """ + originze chain of thought prompt messages, a standard prompt message is like: + Respond to the human as helpfully and accurately as possible. + + {{instruction}} + + You have access to the following tools: + + {{tools}} + + Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input). + Valid action values: "Final Answer" or {{tool_names}} + + Provide only ONE action per $JSON_BLOB, as shown: + + ``` + {{{{ + "action": $TOOL_NAME, + "action_input": $ACTION_INPUT + }}}} + ``` + """ + + self._check_cot_prompt_messages(mode, agent_prompt_message) + + # parse agent prompt message + first_prompt = agent_prompt_message.first_prompt + + # parse tools + tools_str = self._jsonify_tool_prompt_messages(tools) + + # parse tools name + tool_names = '"' + '","'.join([tool.name for tool in tools]) + '"' + + # get system message + system_message = first_prompt.replace("{{instruction}}", instruction) \ + .replace("{{tools}}", tools_str) \ + .replace("{{tool_names}}", tool_names) + + # originze prompt messages + if mode == "chat": + # override system message + overrided = False + prompt_messages = prompt_messages.copy() + for prompt_message in prompt_messages: + if isinstance(prompt_message, SystemPromptMessage): + prompt_message.content = system_message + overrided = True + break + + if not overrided: + prompt_messages.insert(0, SystemPromptMessage( + content=system_message, + )) + + # add assistant message + if len(agent_scratchpad) > 0: + prompt_messages.append(AssistantPromptMessage( + content=agent_scratchpad[-1].thought + "\n" + agent_scratchpad[-1].observation + )) + + # add user message + if len(agent_scratchpad) > 0: + prompt_messages.append(UserPromptMessage( + content=input, + )) + + return prompt_messages + elif mode == "completion": + # parse agent scratchpad + agent_scratchpad_str = self._convert_strachpad_list_to_str(agent_scratchpad) + # parse prompt messages + return [UserPromptMessage( + content=first_prompt.replace("{{instruction}}", instruction) + .replace("{{tools}}", tools_str) + .replace("{{tool_names}}", tool_names) + .replace("{{query}}", input) + .replace("{{agent_scratchpad}}", agent_scratchpad_str), + )] + else: + raise ValueError(f"mode {mode} is not supported") + + def _jsonify_tool_prompt_messages(self, tools: list[PromptMessageTool]) -> str: + """ + jsonify tool prompt messages + """ + tools = jsonable_encoder(tools) + try: + return json.dumps(tools, ensure_ascii=False) + except json.JSONDecodeError: + return json.dumps(tools) \ No newline at end of file diff --git a/api/core/features/assistant_fc_runner.py b/api/core/features/assistant_fc_runner.py new file mode 100644 index 000000000..dfd59527d --- /dev/null +++ b/api/core/features/assistant_fc_runner.py @@ -0,0 +1,335 @@ +import json +import logging + +from typing import Union, Generator, Dict, Any, Tuple, List + +from core.model_runtime.entities.message_entities import PromptMessage, UserPromptMessage,\ + SystemPromptMessage, AssistantPromptMessage, ToolPromptMessage, PromptMessageTool +from core.model_runtime.entities.llm_entities import LLMResultChunk, LLMResult, LLMUsage +from core.model_manager import ModelInstance +from core.application_queue_manager import PublishFrom + +from core.tools.errors import ToolInvokeError, ToolNotFoundError, \ + ToolNotSupportedError, ToolProviderNotFoundError, ToolParamterValidationError, \ + ToolProviderCredentialValidationError + +from core.features.assistant_base_runner import BaseAssistantApplicationRunner + +from models.model import Conversation, Message, MessageAgentThought + +logger = logging.getLogger(__name__) + +class AssistantFunctionCallApplicationRunner(BaseAssistantApplicationRunner): + def run(self, model_instance: ModelInstance, + conversation: Conversation, + message: Message, + query: str, + ) -> Generator[LLMResultChunk, None, None]: + """ + Run FunctionCall agent application + """ + app_orchestration_config = self.app_orchestration_config + + prompt_template = self.app_orchestration_config.prompt_template.simple_prompt_template or '' + prompt_messages = self.history_prompt_messages + prompt_messages = self.organize_prompt_messages( + prompt_template=prompt_template, + query=query, + prompt_messages=prompt_messages + ) + + # convert tools into ModelRuntime Tool format + prompt_messages_tools: List[PromptMessageTool] = [] + tool_instances = {} + for tool in self.app_orchestration_config.agent.tools if self.app_orchestration_config.agent else []: + try: + prompt_tool, tool_entity = self._convert_tool_to_prompt_message_tool(tool) + except Exception: + # api tool may be deleted + continue + # save tool entity + tool_instances[tool.tool_name] = tool_entity + # save prompt tool + prompt_messages_tools.append(prompt_tool) + + # convert dataset tools into ModelRuntime Tool format + for dataset_tool in self.dataset_tools: + prompt_tool = self._convert_dataset_retriever_tool_to_prompt_message_tool(dataset_tool) + # save prompt tool + prompt_messages_tools.append(prompt_tool) + # save tool entity + tool_instances[dataset_tool.identity.name] = dataset_tool + + iteration_step = 1 + max_iteration_steps = min(app_orchestration_config.agent.max_iteration, 5) + 1 + + # continue to run until there is not any tool call + function_call_state = True + agent_thoughts: List[MessageAgentThought] = [] + llm_usage = { + 'usage': None + } + final_answer = '' + + def increase_usage(final_llm_usage_dict: Dict[str, LLMUsage], usage: LLMUsage): + if not final_llm_usage_dict['usage']: + final_llm_usage_dict['usage'] = usage + else: + llm_usage = final_llm_usage_dict['usage'] + llm_usage.prompt_tokens += usage.prompt_tokens + llm_usage.completion_tokens += usage.completion_tokens + llm_usage.prompt_price += usage.prompt_price + llm_usage.completion_price += usage.completion_price + + while function_call_state and iteration_step <= max_iteration_steps: + function_call_state = False + + if iteration_step == max_iteration_steps: + # the last iteration, remove all tools + prompt_messages_tools = [] + + message_file_ids = [] + agent_thought = self.create_agent_thought( + message_id=message.id, + message='', + tool_name='', + tool_input='', + messages_ids=message_file_ids + ) + self.queue_manager.publish_agent_thought(agent_thought, PublishFrom.APPLICATION_MANAGER) + + # recale llm max tokens + self.recale_llm_max_tokens(self.model_config, prompt_messages) + # invoke model + chunks: Generator[LLMResultChunk, None, None] = model_instance.invoke_llm( + prompt_messages=prompt_messages, + model_parameters=app_orchestration_config.model_config.parameters, + tools=prompt_messages_tools, + stop=app_orchestration_config.model_config.stop, + stream=True, + user=self.user_id, + callbacks=[], + ) + + tool_calls: List[Tuple[str, str, Dict[str, Any]]] = [] + + # save full response + response = '' + + # save tool call names and inputs + tool_call_names = '' + tool_call_inputs = '' + + current_llm_usage = None + + for chunk in chunks: + # check if there is any tool call + if self.check_tool_calls(chunk): + function_call_state = True + tool_calls.extend(self.extract_tool_calls(chunk)) + tool_call_names = ';'.join([tool_call[1] for tool_call in tool_calls]) + try: + tool_call_inputs = json.dumps({ + tool_call[1]: tool_call[2] for tool_call in tool_calls + }, ensure_ascii=False) + except json.JSONDecodeError as e: + # ensure ascii to avoid encoding error + tool_call_inputs = json.dumps({ + tool_call[1]: tool_call[2] for tool_call in tool_calls + }) + + if chunk.delta.message and chunk.delta.message.content: + if isinstance(chunk.delta.message.content, list): + for content in chunk.delta.message.content: + response += content.data + else: + response += chunk.delta.message.content + + if chunk.delta.usage: + increase_usage(llm_usage, chunk.delta.usage) + current_llm_usage = chunk.delta.usage + + yield chunk + + # save thought + self.save_agent_thought( + agent_thought=agent_thought, + tool_name=tool_call_names, + tool_input=tool_call_inputs, + thought=response, + observation=None, + answer=response, + messages_ids=[], + llm_usage=current_llm_usage + ) + + self.queue_manager.publish_agent_thought(agent_thought, PublishFrom.APPLICATION_MANAGER) + + final_answer += response + '\n' + + # call tools + tool_responses = [] + for tool_call_id, tool_call_name, tool_call_args in tool_calls: + tool_instance = tool_instances.get(tool_call_name) + if not tool_instance: + logger.error(f"failed to find tool instance: {tool_call_name}") + tool_response = { + "tool_call_id": tool_call_id, + "tool_call_name": tool_call_name, + "tool_response": f"there is not a tool named {tool_call_name}" + } + tool_responses.append(tool_response) + else: + # invoke tool + error_response = None + try: + tool_invoke_message = tool_instance.invoke( + user_id=self.user_id, + tool_paramters=tool_call_args, + ) + # transform tool invoke message to get LLM friendly message + tool_invoke_message = self.transform_tool_invoke_messages(tool_invoke_message) + # extract binary data from tool invoke message + binary_files = self.extract_tool_response_binary(tool_invoke_message) + # create message file + message_files = self.create_message_files(binary_files) + # publish files + for message_file, save_as in message_files: + if save_as: + self.variables_pool.set_file(tool_name=tool_call_name, value=message_file.id, name=save_as) + + # publish message file + self.queue_manager.publish_message_file(message_file, PublishFrom.APPLICATION_MANAGER) + # add message file ids + message_file_ids.append(message_file.id) + + except ToolProviderCredentialValidationError as e: + error_response = f"Plese check your tool provider credentials" + except ( + ToolNotFoundError, ToolNotSupportedError, ToolProviderNotFoundError + ) as e: + error_response = f"there is not a tool named {tool_call_name}" + except ( + ToolParamterValidationError + ) as e: + error_response = f"tool paramters validation error: {e}, please check your tool paramters" + except ToolInvokeError as e: + error_response = f"tool invoke error: {e}" + except Exception as e: + error_response = f"unknown error: {e}" + + if error_response: + observation = error_response + logger.error(error_response) + tool_response = { + "tool_call_id": tool_call_id, + "tool_call_name": tool_call_name, + "tool_response": error_response + } + tool_responses.append(tool_response) + else: + observation = self._convert_tool_response_to_str(tool_invoke_message) + tool_response = { + "tool_call_id": tool_call_id, + "tool_call_name": tool_call_name, + "tool_response": observation + } + tool_responses.append(tool_response) + + prompt_messages = self.organize_prompt_messages( + prompt_template=prompt_template, + query=None, + tool_call_id=tool_call_id, + tool_call_name=tool_call_name, + tool_response=tool_response['tool_response'], + prompt_messages=prompt_messages, + ) + + if len(tool_responses) > 0: + # save agent thought + self.save_agent_thought( + agent_thought=agent_thought, + tool_name=None, + tool_input=None, + thought=None, + observation=tool_response['tool_response'], + answer=None, + messages_ids=message_file_ids + ) + self.queue_manager.publish_agent_thought(agent_thought, PublishFrom.APPLICATION_MANAGER) + + # update prompt messages + if response.strip(): + prompt_messages.append(AssistantPromptMessage( + content=response, + )) + + # update prompt tool + for prompt_tool in prompt_messages_tools: + self.update_prompt_message_tool(tool_instances[prompt_tool.name], prompt_tool) + + iteration_step += 1 + + self.update_db_variables(self.variables_pool, self.db_variables_pool) + # publish end event + self.queue_manager.publish_message_end(LLMResult( + model=model_instance.model, + prompt_messages=prompt_messages, + message=AssistantPromptMessage( + content=final_answer, + ), + usage=llm_usage['usage'], + system_fingerprint='' + ), PublishFrom.APPLICATION_MANAGER) + + def check_tool_calls(self, llm_result_chunk: LLMResultChunk) -> bool: + """ + Check if there is any tool call in llm result chunk + """ + if llm_result_chunk.delta.message.tool_calls: + return True + return False + + def extract_tool_calls(self, llm_result_chunk: LLMResultChunk) -> Union[None, List[Tuple[str, str, Dict[str, Any]]]]: + """ + Extract tool calls from llm result chunk + + Returns: + List[Tuple[str, str, Dict[str, Any]]]: [(tool_call_id, tool_call_name, tool_call_args)] + """ + tool_calls = [] + for prompt_message in llm_result_chunk.delta.message.tool_calls: + tool_calls.append(( + prompt_message.id, + prompt_message.function.name, + json.loads(prompt_message.function.arguments), + )) + + return tool_calls + + def organize_prompt_messages(self, prompt_template: str, + query: str = None, + tool_call_id: str = None, tool_call_name: str = None, tool_response: str = None, + prompt_messages: list[PromptMessage] = None + ) -> list[PromptMessage]: + """ + Organize prompt messages + """ + + if not prompt_messages: + prompt_messages = [ + SystemPromptMessage(content=prompt_template), + UserPromptMessage(content=query), + ] + else: + if tool_response: + prompt_messages = prompt_messages.copy() + prompt_messages.append( + ToolPromptMessage( + content=tool_response, + tool_call_id=tool_call_id, + name=tool_call_name, + ) + ) + + return prompt_messages \ No newline at end of file diff --git a/api/core/features/dataset_retrieval.py b/api/core/features/dataset_retrieval.py index 90ca6c42e..f8fcea7c1 100644 --- a/api/core/features/dataset_retrieval.py +++ b/api/core/features/dataset_retrieval.py @@ -6,8 +6,8 @@ from core.entities.application_entities import DatasetEntity, DatasetRetrieveCon from core.memory.token_buffer_memory import TokenBufferMemory from core.model_runtime.entities.model_entities import ModelFeature from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel -from core.tool.dataset_multi_retriever_tool import DatasetMultiRetrieverTool -from core.tool.dataset_retriever_tool import DatasetRetrieverTool +from core.tools.tool.dataset_retriever.dataset_multi_retriever_tool import DatasetMultiRetrieverTool +from core.tools.tool.dataset_retriever.dataset_retriever_tool import DatasetRetrieverTool from extensions.ext_database import db from langchain.tools import BaseTool from models.dataset import Dataset diff --git a/api/core/file/file_obj.py b/api/core/file/file_obj.py index 3ebe53160..626dbbca4 100644 --- a/api/core/file/file_obj.py +++ b/api/core/file/file_obj.py @@ -22,6 +22,7 @@ class FileType(enum.Enum): class FileTransferMethod(enum.Enum): REMOTE_URL = 'remote_url' LOCAL_FILE = 'local_file' + TOOL_FILE = 'tool_file' @staticmethod def value_of(value): @@ -30,6 +31,16 @@ class FileTransferMethod(enum.Enum): return member raise ValueError(f"No matching enum found for value '{value}'") +class FileBelongsTo(enum.Enum): + USER = 'user' + ASSISTANT = 'assistant' + + @staticmethod + def value_of(value): + for member in FileBelongsTo: + if member.value == value: + return member + raise ValueError(f"No matching enum found for value '{value}'") class FileObj(BaseModel): id: Optional[str] diff --git a/api/core/file/message_file_parser.py b/api/core/file/message_file_parser.py index e651745e2..e70a68e70 100644 --- a/api/core/file/message_file_parser.py +++ b/api/core/file/message_file_parser.py @@ -1,7 +1,7 @@ from typing import Dict, List, Optional, Union import requests -from core.file.file_obj import FileObj, FileTransferMethod, FileType +from core.file.file_obj import FileObj, FileTransferMethod, FileType, FileBelongsTo from services.file_service import IMAGE_EXTENSIONS from extensions.ext_database import db from models.account import Account @@ -128,6 +128,9 @@ class MessageFileParser: # group by file type and convert file args or message files to FileObj for file in files: + if file.belongs_to == FileBelongsTo.ASSISTANT.value: + continue + file_obj = self._to_file_obj(file, file_upload_config) if file_obj.type not in type_file_objs: continue diff --git a/api/core/file/tool_file_parser.py b/api/core/file/tool_file_parser.py new file mode 100644 index 000000000..ea8605ac5 --- /dev/null +++ b/api/core/file/tool_file_parser.py @@ -0,0 +1,8 @@ +tool_file_manager = { + 'manager': None +} + +class ToolFileParser: + @staticmethod + def get_tool_file_manager() -> 'ToolFileManager': + return tool_file_manager['manager'] \ No newline at end of file diff --git a/api/core/model_runtime/model_providers/openai/llm/llm.py b/api/core/model_runtime/model_providers/openai/llm/llm.py index 4b6ba4be9..f8fc5db99 100644 --- a/api/core/model_runtime/model_providers/openai/llm/llm.py +++ b/api/core/model_runtime/model_providers/openai/llm/llm.py @@ -485,19 +485,37 @@ class OpenAILargeLanguageModel(_CommonOpenAI, LargeLanguageModel): :return: llm response chunk generator """ full_assistant_content = '' + delta_assistant_message_function_call_storage: ChoiceDeltaFunctionCall = None for chunk in response: if len(chunk.choices) == 0: continue delta = chunk.choices[0] - if delta.finish_reason is None and (delta.delta.content is None or delta.delta.content == ''): + if delta.finish_reason is None and (delta.delta.content is None or delta.delta.content == '') and \ + delta.delta.function_call is None: continue # assistant_message_tool_calls = delta.delta.tool_calls assistant_message_function_call = delta.delta.function_call # extract tool calls from response + if delta_assistant_message_function_call_storage is not None: + # handle process of stream function call + if assistant_message_function_call: + # message has not ended ever + delta_assistant_message_function_call_storage.arguments += assistant_message_function_call.arguments + continue + else: + # message has ended + assistant_message_function_call = delta_assistant_message_function_call_storage + delta_assistant_message_function_call_storage = None + else: + if assistant_message_function_call: + # start of stream function call + delta_assistant_message_function_call_storage = assistant_message_function_call + continue + # tool_calls = self._extract_response_tool_calls(assistant_message_tool_calls) function_call = self._extract_response_function_call(assistant_message_function_call) tool_calls = [function_call] if function_call else [] diff --git a/api/core/tools/README.md b/api/core/tools/README.md new file mode 100644 index 000000000..c7ee81422 --- /dev/null +++ b/api/core/tools/README.md @@ -0,0 +1,25 @@ +# Tools + +This module implements built-in tools used in Agent Assistants and Workflows within Dify. You could define and display your own tools in this module, without modifying the frontend logic. This decoupling allows for easier horizontal scaling of Dify's capabilities. + +## Feature Introduction + +The tools provided for Agents and Workflows are currently divided into two categories: +- `Built-in Tools` are internally implemented within our product and are hardcoded for use in Agents and Workflows. +- `Api-Based Tools` leverage third-party APIs for implementation. You don't need to code to integrate these -- simply provide interface definitions in formats like `OpenAPI` , `Swagger`, or the `OpenAI-plugin` on the front-end. + +### Built-in Tool Providers +![Alt text](docs/zh_Hans/images/index/image.png) + +### API Tool Providers +![Alt text](docs/zh_Hans/images/index/image-1.png) + +## Tool Integration + +To enable developers to build flexible and powerful tools, we provide two guides: + +### [Quick Integration 👈🏻](./docs/en_US/tool_scale_out.md) +Quick integration aims at quickly getting you up to speed with tool integration by walking over an example Google Search tool. + +### [Advanced Integration 👈🏻](./docs/en_US/advanced_scale_out.md) +Advanced integration will offer a deeper dive into the module interfaces, and explain how to implement more complex capabilities, such as generating images, combining multiple tools, and managing the flow of parameters, images, and files between different tools. \ No newline at end of file diff --git a/api/core/tools/README_CN.md b/api/core/tools/README_CN.md new file mode 100644 index 000000000..fda5d0630 --- /dev/null +++ b/api/core/tools/README_CN.md @@ -0,0 +1,27 @@ +# Tools + +该模块提供了各Agent和Workflow中会使用的内置工具的调用、鉴权接口,并为 Dify 提供了统一的工具供应商的信息和凭据表单规则。 + +- 一方面将工具和业务代码解耦,方便开发者对模型横向扩展, +- 另一方面提供了只需在后端定义供应商和工具,即可在前端页面直接展示,无需修改前端逻辑。 + +## 功能介绍 + +对于给Agent和Workflow提供的工具,我们当前将其分为两类: +- `Built-in Tools` 内置工具,即Dify内部实现的工具,通过硬编码的方式提供给Agent和Workflow使用。 +- `Api-Based Tools` 基于API的工具,即通过调用第三方API实现的工具,`Api-Based Tool`不需要再额外定义,只需提供`OpenAPI` `Swagger` `OpenAI plugin`等接口文档即可。 + +### 内置工具供应商 +![Alt text](docs/zh_Hans/images/index/image.png) + +### API工具供应商 +![Alt text](docs/zh_Hans/images/index/image-1.png) + +## 工具接入 +为了实现更灵活更强大的功能,Tools提供了一系列的接口,帮助开发者快速构建想要的工具,本文作为开发者的入门指南,将会以[快速接入](./docs/zh_Hans/tool_scale_out.md)和[高级接入](./docs/zh_Hans/advanced_scale_out.md)两部分介绍如何接入工具。 + +### [快速接入 👈🏻](./docs/zh_Hans/tool_scale_out.md) +快速接入可以帮助你在10~20分钟内完成工具的接入,但是这种接入方式只能实现简单的功能,如果你想要实现更复杂的功能,可以参考下面的高级接入。 + +### [高级接入 👈🏻](./docs/zh_Hans/advanced_scale_out.md) +高级接入将介绍如何实现更复杂的功能配置,包括实现图生图、实现多个工具的组合、实现参数、图片、文件在多个工具之间的流转。 \ No newline at end of file diff --git a/api/core/tools/docs/en_US/advanced_scale_out.md b/api/core/tools/docs/en_US/advanced_scale_out.md new file mode 100644 index 000000000..c6f516e1d --- /dev/null +++ b/api/core/tools/docs/en_US/advanced_scale_out.md @@ -0,0 +1,266 @@ +# Advanced Tool Integration + +Before starting with this advanced guide, please make sure you have a basic understanding of the tool integration process in Dify. Check out [Quick Integration](./tool_scale_out.md) for a quick runthrough. + +## Tool Interface + +We have defined a series of helper methods in the `Tool` class to help developers quickly build more complex tools. + +### Message Return + +Dify supports various message types such as `text`, `link`, `image`, and `file BLOB`. You can return different types of messages to the LLM and users through the following interfaces. + +Please note, some parameters in the following interfaces will be introduced in later sections. + +#### Image URL +You only need to pass the URL of the image, and Dify will automatically download the image and return it to the user. + +```python + def create_image_message(self, image: str, save_as: str = '') -> ToolInvokeMessage: + """ + create an image message + + :param image: the url of the image + :return: the image message + """ +``` + +#### Link +If you need to return a link, you can use the following interface. + +```python + def create_link_message(self, link: str, save_as: str = '') -> ToolInvokeMessage: + """ + create a link message + + :param link: the url of the link + :return: the link message + """ +``` + +#### Text +If you need to return a text message, you can use the following interface. + +```python + def create_text_message(self, text: str, save_as: str = '') -> ToolInvokeMessage: + """ + create a text message + + :param text: the text of the message + :return: the text message + """ +``` + +#### File BLOB +If you need to return the raw data of a file, such as images, audio, video, PPT, Word, Excel, etc., you can use the following interface. + +- `blob` The raw data of the file, of bytes type +- `meta` The metadata of the file, if you know the type of the file, it is best to pass a `mime_type`, otherwise Dify will use `octet/stream` as the default type + +```python + def create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = '') -> ToolInvokeMessage: + """ + create a blob message + + :param blob: the blob + :return: the blob message + """ +``` + +### Shortcut Tools + +In large model applications, we have two common needs: +- First, summarize a long text in advance, and then pass the summary content to the LLM to prevent the original text from being too long for the LLM to handle +- The content obtained by the tool is a link, and the web page information needs to be crawled before it can be returned to the LLM + +To help developers quickly implement these two needs, we provide the following two shortcut tools. + +#### Text Summary Tool + +This tool takes in an user_id and the text to be summarized, and returns the summarized text. Dify will use the default model of the current workspace to summarize the long text. + +```python + def summary(self, user_id: str, content: str) -> str: + """ + summary the content + + :param user_id: the user id + :param content: the content + :return: the summary + """ +``` + +#### Web Page Crawling Tool + +This tool takes in web page link to be crawled and a user_agent (which can be empty), and returns a string containing the information of the web page. The `user_agent` is an optional parameter that can be used to identify the tool. If not passed, Dify will use the default `user_agent`. + +```python + def get_url(self, url: str, user_agent: str = None) -> str: + """ + get url + """ the crawled result +``` + +### Variable Pool + +We have introduced a variable pool in `Tool` to store variables, files, etc. generated during the tool's operation. These variables can be used by other tools during the tool's operation. + +Next, we will use `DallE3` and `Vectorizer.AI` as examples to introduce how to use the variable pool. + +- `DallE3` is an image generation tool that can generate images based on text. Here, we will let `DallE3` generate a logo for a coffee shop +- `Vectorizer.AI` is a vector image conversion tool that can convert images into vector images, so that the images can be infinitely enlarged without distortion. Here, we will convert the PNG icon generated by `DallE3` into a vector image, so that it can be truly used by designers. + +#### DallE3 +First, we use DallE3. After creating the image, we save the image to the variable pool. The code is as follows: + +```python +from typing import Any, Dict, List, Union +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + +from base64 import b64decode + +from openai import OpenAI + +class DallE3Tool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + client = OpenAI( + api_key=self.runtime.credentials['openai_api_key'], + ) + + # prompt + prompt = tool_paramters.get('prompt', '') + if not prompt: + return self.create_text_message('Please input prompt') + + # call openapi dalle3 + response = client.images.generate( + prompt=prompt, model='dall-e-3', + size='1024x1024', n=1, style='vivid', quality='standard', + response_format='b64_json' + ) + + result = [] + for image in response.data: + # Save all images to the variable pool through the save_as parameter. The variable name is self.VARIABLE_KEY.IMAGE.value. If new images are generated later, they will overwrite the previous images. + result.append(self.create_blob_message(blob=b64decode(image.b64_json), + meta={ 'mime_type': 'image/png' }, + save_as=self.VARIABLE_KEY.IMAGE.value)) + + return result +``` + +Note that we used `self.VARIABLE_KEY.IMAGE.value` as the variable name of the image. In order for developers' tools to cooperate with each other, we defined this `KEY`. You can use it freely, or you can choose not to use this `KEY`. Passing a custom KEY is also acceptable. + +#### Vectorizer.AI +Next, we use Vectorizer.AI to convert the PNG icon generated by DallE3 into a vector image. Let's go through the functions we defined here. The code is as follows: + +```python +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter +from core.tools.errors import ToolProviderCredentialValidationError + +from typing import Any, Dict, List, Union +from httpx import post +from base64 import b64decode + +class VectorizerTool(BuiltinTool): + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + Tool invocation, the image variable name needs to be passed in from here, so that we can get the image from the variable pool + """ + + + def get_runtime_parameters(self) -> List[ToolParamter]: + """ + Override the tool parameter list, we can dynamically generate the parameter list based on the actual situation in the current variable pool, so that the LLM can generate the form based on the parameter list + """ + + + def is_tool_avaliable(self) -> bool: + """ + Whether the current tool is available, if there is no image in the current variable pool, then we don't need to display this tool, just return False here + """ +``` + +Next, let's implement these three functions + +```python +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter +from core.tools.errors import ToolProviderCredentialValidationError + +from typing import Any, Dict, List, Union +from httpx import post +from base64 import b64decode + +class VectorizerTool(BuiltinTool): + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + api_key_name = self.runtime.credentials.get('api_key_name', None) + api_key_value = self.runtime.credentials.get('api_key_value', None) + + if not api_key_name or not api_key_value: + raise ToolProviderCredentialValidationError('Please input api key name and value') + + # Get image_id, the definition of image_id can be found in get_runtime_parameters + image_id = tool_paramters.get('image_id', '') + if not image_id: + return self.create_text_message('Please input image id') + + # Get the image generated by DallE from the variable pool + image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE) + if not image_binary: + return self.create_text_message('Image not found, please request user to generate image firstly.') + + # Generate vector image + response = post( + 'https://vectorizer.ai/api/v1/vectorize', + files={ 'image': image_binary }, + data={ 'mode': 'test' }, + auth=(api_key_name, api_key_value), + timeout=30 + ) + + if response.status_code != 200: + raise Exception(response.text) + + return [ + self.create_text_message('the vectorized svg is saved as an image.'), + self.create_blob_message(blob=response.content, + meta={'mime_type': 'image/svg+xml'}) + ] + + def get_runtime_parameters(self) -> List[ToolParamter]: + """ + override the runtime parameters + """ + # Here, we override the tool parameter list, define the image_id, and set its option list to all images in the current variable pool. The configuration here is consistent with the configuration in yaml. + return [ + ToolParamter.get_simple_instance( + name='image_id', + llm_description=f'the image id that you want to vectorize, \ + and the image id should be specified in \ + {[i.name for i in self.list_default_image_variables()]}', + type=ToolParamter.ToolParameterType.SELECT, + required=True, + options=[i.name for i in self.list_default_image_variables()] + ) + ] + + def is_tool_avaliable(self) -> bool: + # Only when there are images in the variable pool, the LLM needs to use this tool + return len(self.list_default_image_variables()) > 0 +``` + +It's worth noting that we didn't actually use `image_id` here. We assumed that there must be an image in the default variable pool when calling this tool, so we directly used `image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE)` to get the image. In cases where the model's capabilities are weak, we recommend developers to do the same, which can effectively improve fault tolerance and avoid the model passing incorrect parameters. \ No newline at end of file diff --git a/api/core/tools/docs/en_US/tool_scale_out.md b/api/core/tools/docs/en_US/tool_scale_out.md new file mode 100644 index 000000000..90aa38bfd --- /dev/null +++ b/api/core/tools/docs/en_US/tool_scale_out.md @@ -0,0 +1,212 @@ +# Quick Tool Integration + +Here, we will use GoogleSearch as an example to demonstrate how to quickly integrate a tool. + +## 1. Prepare the Tool Provider yaml + +### Introduction +This yaml declares a new tool provider, and includes information like the provider's name, icon, author, and other details that are fetched by the frontend for display. + +### Example + +We need to create a `google` module (folder) under `core/tools/provider/builtin`, and create `google.yaml`. The name must be consistent with the module name. + +Subsequently, all operations related to this tool will be carried out under this module. + +```yaml +identity: # Basic information of the tool provider + author: Dify # Author + name: google # Name, unique, no duplication with other providers + label: # Label for frontend display + en_US: Google # English label + zh_Hans: Google # Chinese label + description: # Description for frontend display + en_US: Google # English description + zh_Hans: Google # Chinese description + icon: icon.svg # Icon, needs to be placed in the _assets folder of the current module + +``` + - The `identity` field is mandatory, it contains the basic information of the tool provider, including author, name, label, description, icon, etc. + - The icon needs to be placed in the `_assets` folder of the current module, you can refer to [here](../../provider/builtin/google/_assets/icon.svg). + +## 2. Prepare Provider Credentials + +Google, as a third-party tool, uses the API provided by SerpApi, which requires an API Key to use. This means that this tool needs a credential to use. For tools like `wikipedia`, there is no need to fill in the credential field, you can refer to [here](../../provider/builtin/wikipedia/wikipedia.yaml). + +After configuring the credential field, the effect is as follows: +```yaml +identity: + author: Dify + name: google + label: + en_US: Google + zh_Hans: Google + description: + en_US: Google + zh_Hans: Google + icon: icon.svg +credentails_for_provider: # Credential field + serpapi_api_key: # Credential field name + type: secret-input # Credential field type + required: true # Required or not + label: # Credential field label + en_US: SerpApi API key # English label + zh_Hans: SerpApi API key # Chinese label + placeholder: # Credential field placeholder + en_US: Please input your SerpApi API key # English placeholder + zh_Hans: 请输入你的 SerpApi API key # Chinese placeholder + help: # Credential field help text + en_US: Get your SerpApi API key from SerpApi # English help text + zh_Hans: 从 SerpApi 获取您的 SerpApi API key # Chinese help text + url: https://serpapi.com/manage-api-key # Credential field help link + +``` + +- `type`: Credential field type, currently can be either `secret-input`, `text-input`, or `select` , corresponding to password input box, text input box, and drop-down box, respectively. If set to `secret-input`, it will mask the input content on the frontend, and the backend will encrypt the input content. + +## 3. Prepare Tool yaml +A provider can have multiple tools, each tool needs a yaml file to describe, this file contains the basic information, parameters, output, etc. of the tool. + +Still taking GoogleSearch as an example, we need to create a `tools` module under the `google` module, and create `tools/google_search.yaml`, the content is as follows. + +```yaml +identity: # Basic information of the tool + name: google_search # Tool name, unique, no duplication with other tools + author: Dify # Author + label: # Label for frontend display + en_US: GoogleSearch # English label + zh_Hans: 谷歌搜索 # Chinese label +description: # Description for frontend display + human: # Introduction for frontend display, supports multiple languages + en_US: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query. + zh_Hans: 一个用于执行 Google SERP 搜索并提取片段和网页的工具。输入应该是一个搜索查询。 + llm: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query. # Introduction passed to LLM, in order to make LLM better understand this tool, we suggest to write as detailed information about this tool as possible here, so that LLM can understand and use this tool +parameters: # Parameter list + - name: query # Parameter name + type: string # Parameter type + required: true # Required or not + label: # Parameter label + en_US: Query string # English label + zh_Hans: 查询语句 # Chinese label + human_description: # Introduction for frontend display, supports multiple languages + en_US: used for searching + zh_Hans: 用于搜索网页内容 + llm_description: key words for searching # Introduction passed to LLM, similarly, in order to make LLM better understand this parameter, we suggest to write as detailed information about this parameter as possible here, so that LLM can understand this parameter + form: llm # Form type, llm means this parameter needs to be inferred by Agent, the frontend will not display this parameter + - name: result_type + type: select # Parameter type + required: true + options: # Drop-down box options + - value: text + label: + en_US: text + zh_Hans: 文本 + - value: link + label: + en_US: link + zh_Hans: 链接 + default: link + label: + en_US: Result type + zh_Hans: 结果类型 + human_description: + en_US: used for selecting the result type, text or link + zh_Hans: 用于选择结果类型,使用文本还是链接进行展示 + form: form # Form type, form means this parameter needs to be filled in by the user on the frontend before the conversation starts + +``` + +- The `identity` field is mandatory, it contains the basic information of the tool, including name, author, label, description, etc. +- `parameters` Parameter list + - `name` Parameter name, unique, no duplication with other parameters + - `type` Parameter type, currently supports `string`, `number`, `boolean`, `select` four types, corresponding to string, number, boolean, drop-down box + - `required` Required or not + - In `llm` mode, if the parameter is required, the Agent is required to infer this parameter + - In `form` mode, if the parameter is required, the user is required to fill in this parameter on the frontend before the conversation starts + - `options` Parameter options + - In `llm` mode, Dify will pass all options to LLM, LLM can infer based on these options + - In `form` mode, when `type` is `select`, the frontend will display these options + - `default` Default value + - `label` Parameter label, for frontend display + - `human_description` Introduction for frontend display, supports multiple languages + - `llm_description` Introduction passed to LLM, in order to make LLM better understand this parameter, we suggest to write as detailed information about this parameter as possible here, so that LLM can understand this parameter + - `form` Form type, currently supports `llm`, `form` two types, corresponding to Agent self-inference and frontend filling + +## 4. Add Tool Logic +After completing the tool configuration, we can start writing the tool code that defines how it is invoked. + +Create `google_search.py` under the `google/tools` module, the content is as follows. + +```python +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage + +from typing import Any, Dict, List, Union + +class GoogleSearchTool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + query = tool_paramters['query'] + result_type = tool_paramters['result_type'] + api_key = self.runtime.credentials['serpapi_api_key'] + # TODO: search with serpapi + result = SerpAPI(api_key).run(query, result_type=result_type) + + if result_type == 'text': + return self.create_text_message(text=result) + return self.create_link_message(link=result) +``` + +### Parameters +The overall logic of the tool is in the `_invoke` method, this method accepts two parameters: `user_id` and `tool_paramters`, which represent the user ID and tool parameters respectively + +### Return Data +When the tool returns, you can choose to return one message or multiple messages, here we return one message, using `create_text_message` and `create_link_message` can create a text message or a link message. + +## 5. Add Provider Code +Finally, we need to create a provider class under the provider module to implement the provider's credential verification logic. If the credential verification fails, it will throw a `ToolProviderCredentialValidationError` exception. + +Create `google.py` under the `google` module, the content is as follows. + +```python +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolProviderType +from core.tools.tool.tool import Tool +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.google.tools.google_search import GoogleSearchTool + +from typing import Any, Dict + +class GoogleProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + # 1. Here you need to instantiate a GoogleSearchTool with GoogleSearchTool(), it will automatically load the yaml configuration of GoogleSearchTool, but at this time it does not have credential information inside + # 2. Then you need to use the fork_tool_runtime method to pass the current credential information to GoogleSearchTool + # 3. Finally, invoke it, the parameters need to be passed according to the parameter rules configured in the yaml of GoogleSearchTool + GoogleSearchTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "query": "test", + "result_type": "link" + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) +``` + +## Completion +After the above steps are completed, we can see this tool on the frontend, and it can be used in the Agent. + +Of course, because google_search needs a credential, before using it, you also need to input your credentials on the frontend. + +![Alt text](../zh_Hans/images/index/image-2.png) \ No newline at end of file diff --git a/api/core/tools/docs/zh_Hans/advanced_scale_out.md b/api/core/tools/docs/zh_Hans/advanced_scale_out.md new file mode 100644 index 000000000..520b48d28 --- /dev/null +++ b/api/core/tools/docs/zh_Hans/advanced_scale_out.md @@ -0,0 +1,266 @@ +# 高级接入Tool + +在开始高级接入之前,请确保你已经阅读过[快速接入](./tool_scale_out.md),并对Dify的工具接入流程有了基本的了解。 + +## 工具接口 + +我们在`Tool`类中定义了一系列快捷方法,用于帮助开发者快速构较为复杂的工具 + +### 消息返回 + +Dify支持`文本` `链接` `图片` `文件BLOB` 等多种消息类型,你可以通过以下几个接口返回不同类型的消息给LLM和用户。 + +注意,在下面的接口中的部分参数将在后面的章节中介绍。 + +#### 图片URL +只需要传递图片的URL即可,Dify会自动下载图片并返回给用户。 + +```python + def create_image_message(self, image: str, save_as: str = '') -> ToolInvokeMessage: + """ + create an image message + + :param image: the url of the image + :return: the image message + """ +``` + +#### 链接 +如果你需要返回一个链接,可以使用以下接口。 + +```python + def create_link_message(self, link: str, save_as: str = '') -> ToolInvokeMessage: + """ + create a link message + + :param link: the url of the link + :return: the link message + """ +``` + +#### 文本 +如果你需要返回一个文本消息,可以使用以下接口。 + +```python + def create_text_message(self, text: str, save_as: str = '') -> ToolInvokeMessage: + """ + create a text message + + :param text: the text of the message + :return: the text message + """ +``` + +#### 文件BLOB +如果你需要返回文件的原始数据,如图片、音频、视频、PPT、Word、Excel等,可以使用以下接口。 + +- `blob` 文件的原始数据,bytes类型 +- `meta` 文件的元数据,如果你知道该文件的类型,最好传递一个`mime_type`,否则Dify将使用`octet/stream`作为默认类型 + +```python + def create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = '') -> ToolInvokeMessage: + """ + create a blob message + + :param blob: the blob + :return: the blob message + """ +``` + +### 快捷工具 + +在大模型应用中,我们有两种常见的需求: +- 先将很长的文本进行提前总结,然后再将总结内容传递给LLM,以防止原文本过长导致LLM无法处理 +- 工具获取到的内容是一个链接,需要爬取网页信息后再返回给LLM + +为了帮助开发者快速实现这两种需求,我们提供了以下两个快捷工具。 + +#### 文本总结工具 + +该工具需要传入user_id和需要进行总结的文本,返回一个总结后的文本,Dify会使用当前工作空间的默认模型对长文本进行总结。 + +```python + def summary(self, user_id: str, content: str) -> str: + """ + summary the content + + :param user_id: the user id + :param content: the content + :return: the summary + """ +``` + +#### 网页爬取工具 + +该工具需要传入需要爬取的网页链接和一个user_agent(可为空),返回一个包含该网页信息的字符串,其中`user_agent`是可选参数,可以用来识别工具,如果不传递,Dify将使用默认的`user_agent`。 + +```python + def get_url(self, url: str, user_agent: str = None) -> str: + """ + get url + """ the crawled result +``` + +### 变量池 + +我们在`Tool`中引入了一个变量池,用于存储工具运行过程中产生的变量、文件等,这些变量可以在工具运行过程中被其他工具使用。 + +下面,我们以`DallE3`和`Vectorizer.AI`为例,介绍如何使用变量池。 + +- `DallE3`是一个图片生成工具,它可以根据文本生成图片,在这里,我们将让`DallE3`生成一个咖啡厅的Logo +- `Vectorizer.AI`是一个矢量图转换工具,它可以将图片转换为矢量图,使得图片可以无限放大而不失真,在这里,我们将`DallE3`生成的PNG图标转换为矢量图,从而可以真正被设计师使用。 + +#### DallE3 +首先我们使用DallE3,在创建完图片以后,我们将图片保存到变量池中,代码如下 + +```python +from typing import Any, Dict, List, Union +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + +from base64 import b64decode + +from openai import OpenAI + +class DallE3Tool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + client = OpenAI( + api_key=self.runtime.credentials['openai_api_key'], + ) + + # prompt + prompt = tool_paramters.get('prompt', '') + if not prompt: + return self.create_text_message('Please input prompt') + + # call openapi dalle3 + response = client.images.generate( + prompt=prompt, model='dall-e-3', + size='1024x1024', n=1, style='vivid', quality='standard', + response_format='b64_json' + ) + + result = [] + for image in response.data: + # 将所有图片通过save_as参数保存到变量池中,变量名为self.VARIABLE_KEY.IMAGE.value,如果如果后续有新的图片生成,那么将会覆盖之前的图片 + result.append(self.create_blob_message(blob=b64decode(image.b64_json), + meta={ 'mime_type': 'image/png' }, + save_as=self.VARIABLE_KEY.IMAGE.value)) + + return result +``` + +我们可以注意到这里我们使用了`self.VARIABLE_KEY.IMAGE.value`作为图片的变量名,为了便于开发者们的工具能够互相配合,我们定义了这个`KEY`,大家可以自由使用,也可以不使用这个`KEY`,传递一个自定义的KEY也是可以的。 + +#### Vectorizer.AI +接下来我们使用Vectorizer.AI,将DallE3生成的PNG图标转换为矢量图,我们先来过一遍我们在这里定义的函数,代码如下 + +```python +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter +from core.tools.errors import ToolProviderCredentialValidationError + +from typing import Any, Dict, List, Union +from httpx import post +from base64 import b64decode + +class VectorizerTool(BuiltinTool): + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + 工具调用,图片变量名需要从这里传递进来,从而我们就可以从变量池中获取到图片 + """ + + + def get_runtime_parameters(self) -> List[ToolParamter]: + """ + 重写工具参数列表,我们可以根据当前变量池里的实际情况来动态生成参数列表,从而LLM可以根据参数列表来生成表单 + """ + + + def is_tool_avaliable(self) -> bool: + """ + 当前工具是否可用,如果当前变量池中没有图片,那么我们就不需要展示这个工具,这里返回False即可 + """ +``` + +接下来我们来实现这三个函数 + +```python +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter +from core.tools.errors import ToolProviderCredentialValidationError + +from typing import Any, Dict, List, Union +from httpx import post +from base64 import b64decode + +class VectorizerTool(BuiltinTool): + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + api_key_name = self.runtime.credentials.get('api_key_name', None) + api_key_value = self.runtime.credentials.get('api_key_value', None) + + if not api_key_name or not api_key_value: + raise ToolProviderCredentialValidationError('Please input api key name and value') + + # 获取image_id,image_id的定义可以在get_runtime_parameters中找到 + image_id = tool_paramters.get('image_id', '') + if not image_id: + return self.create_text_message('Please input image id') + + # 从变量池中获取到之前DallE生成的图片 + image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE) + if not image_binary: + return self.create_text_message('Image not found, please request user to generate image firstly.') + + # 生成矢量图 + response = post( + 'https://vectorizer.ai/api/v1/vectorize', + files={ 'image': image_binary }, + data={ 'mode': 'test' }, + auth=(api_key_name, api_key_value), + timeout=30 + ) + + if response.status_code != 200: + raise Exception(response.text) + + return [ + self.create_text_message('the vectorized svg is saved as an image.'), + self.create_blob_message(blob=response.content, + meta={'mime_type': 'image/svg+xml'}) + ] + + def get_runtime_parameters(self) -> List[ToolParamter]: + """ + override the runtime parameters + """ + # 这里,我们重写了工具参数列表,定义了image_id,并设置了它的选项列表为当前变量池中的所有图片,这里的配置与yaml中的配置是一致的 + return [ + ToolParamter.get_simple_instance( + name='image_id', + llm_description=f'the image id that you want to vectorize, \ + and the image id should be specified in \ + {[i.name for i in self.list_default_image_variables()]}', + type=ToolParamter.ToolParameterType.SELECT, + required=True, + options=[i.name for i in self.list_default_image_variables()] + ) + ] + + def is_tool_avaliable(self) -> bool: + # 只有当变量池中有图片时,LLM才需要使用这个工具 + return len(self.list_default_image_variables()) > 0 +``` + +可以注意到的是,我们这里其实并没有使用到`image_id`,我们已经假设了调用这个工具的时候一定有一张图片在默认的变量池中,所以直接使用了`image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE)`来获取图片,在模型能力较弱的情况下,我们建议开发者们也这样做,可以有效提升容错率,避免模型传递错误的参数。 \ No newline at end of file diff --git a/api/core/tools/docs/zh_Hans/images/index/image-1.png b/api/core/tools/docs/zh_Hans/images/index/image-1.png new file mode 100644 index 0000000000000000000000000000000000000000..3bb146ec90617d4e955c8f774f9b0da7c7369ddc GIT binary patch literal 248210 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 u@=5vOe$2CrRD$TK@OV8u#4f%|*8 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%0AA*Zv>k^kJ}v6I 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≈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 =>GiIeMU~sLkb7&Vuin6 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�< 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

$O{R0la_8@qg^+>}|XgV92|}-UqM@ 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≈WL8mxs3GSbSibU1OXvsX|p;3-7&?ul2zhhY!4l~ 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

qqsz69rv^y)%>XIOh?AG{cOU1EZ+Y?ywsoHp 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 Mq@I9q($r5-%uW5c~YCyO* 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

o)z|Z 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 z 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%0A70E3Hh!dwCobxz3XF`8CJ~S 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

xvMwtJf7;;2;LM|w~0?`^|^PD)T8 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 Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + query = tool_paramters['query'] + result_type = tool_paramters['result_type'] + api_key = self.runtime.credentials['serpapi_api_key'] + # TODO: search with serpapi + result = SerpAPI(api_key).run(query, result_type=result_type) + + if result_type == 'text': + return self.create_text_message(text=result) + return self.create_link_message(link=result) +``` + +### 参数 +工具的整体逻辑都在`_invoke`方法中,这个方法接收两个参数:`user_id`和`tool_paramters`,分别表示用户ID和工具参数 + +### 返回数据 +在工具返回时,你可以选择返回一个消息或者多个消息,这里我们返回一个消息,使用`create_text_message`和`create_link_message`可以创建一个文本消息或者一个链接消息。 + +## 5. 准备供应商代码 +最后,我们需要在供应商模块下创建一个供应商类,用于实现供应商的凭据验证逻辑,如果凭据验证失败,将会抛出`ToolProviderCredentialValidationError`异常。 + +在`google`模块下创建`google.py`,内容如下。 + +```python +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolProviderType +from core.tools.tool.tool import Tool +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.google.tools.google_search import GoogleSearchTool + +from typing import Any, Dict + +class GoogleProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + # 1. 此处需要使用GoogleSearchTool()实例化一个GoogleSearchTool,它会自动加载GoogleSearchTool的yaml配置,但是此时它内部没有凭据信息 + # 2. 随后需要使用fork_tool_runtime方法,将当前的凭据信息传递给GoogleSearchTool + # 3. 最后invoke即可,参数需要根据GoogleSearchTool的yaml中配置的参数规则进行传递 + GoogleSearchTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "query": "test", + "result_type": "link" + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) +``` + +## 完成 +当上述步骤完成以后,我们就可以在前端看到这个工具了,并且可以在Agent中使用这个工具。 + +当然,因为google_search需要一个凭据,在使用之前,还需要在前端配置它的凭据。 + +![Alt text](images/index/image-2.png) diff --git a/api/core/tools/entities/common_entities.py b/api/core/tools/entities/common_entities.py new file mode 100644 index 000000000..13c27b57e --- /dev/null +++ b/api/core/tools/entities/common_entities.py @@ -0,0 +1,22 @@ +from typing import Optional + +from pydantic import BaseModel + + +class I18nObject(BaseModel): + """ + Model class for i18n object. + """ + zh_Hans: Optional[str] = None + en_US: str + + def __init__(self, **data): + super().__init__(**data) + if not self.zh_Hans: + self.zh_Hans = self.en_US + + def to_dict(self) -> dict: + return { + 'zh_Hans': self.zh_Hans, + 'en_US': self.en_US, + } \ No newline at end of file diff --git a/api/core/tools/entities/constant.py b/api/core/tools/entities/constant.py new file mode 100644 index 000000000..2e75fedf9 --- /dev/null +++ b/api/core/tools/entities/constant.py @@ -0,0 +1,3 @@ +class DEFAULT_PROVIDERS: + API_BASED = '__api_based' + APP_BASED = '__app_based' \ No newline at end of file diff --git a/api/core/tools/entities/tool_bundle.py b/api/core/tools/entities/tool_bundle.py new file mode 100644 index 000000000..51ff11b9f --- /dev/null +++ b/api/core/tools/entities/tool_bundle.py @@ -0,0 +1,34 @@ +from pydantic import BaseModel +from typing import Dict, Optional, Any, List + +from core.tools.entities.tool_entities import ToolProviderType, ToolParamter + +class ApiBasedToolBundle(BaseModel): + """ + This class is used to store the schema information of an api based tool. such as the url, the method, the parameters, etc. + """ + # server_url + server_url: str + # method + method: str + # summary + summary: Optional[str] = None + # operation_id + operation_id: str = None + # parameters + parameters: Optional[List[ToolParamter]] = None + # author + author: str + # icon + icon: Optional[str] = None + # openapi operation + openapi: dict + +class AppToolBundle(BaseModel): + """ + This class is used to store the schema information of an tool for an app. + """ + type: ToolProviderType + credential: Optional[Dict[str, Any]] = None + provider_id: str + tool_name: str \ No newline at end of file diff --git a/api/core/tools/entities/tool_entities.py b/api/core/tools/entities/tool_entities.py new file mode 100644 index 000000000..b17bce540 --- /dev/null +++ b/api/core/tools/entities/tool_entities.py @@ -0,0 +1,305 @@ +from pydantic import BaseModel, Field +from enum import Enum +from typing import Optional, List, Dict, Any, Union, cast + +from core.tools.entities.common_entities import I18nObject + +class ToolProviderType(Enum): + """ + Enum class for tool provider + """ + BUILT_IN = "built-in" + APP_BASED = "app-based" + API_BASED = "api-based" + + @classmethod + def value_of(cls, value: str) -> 'ToolProviderType': + """ + Get value of given mode. + + :param value: mode value + :return: mode + """ + for mode in cls: + if mode.value == value: + return mode + raise ValueError(f'invalid mode value {value}') + +class ApiProviderSchemaType(Enum): + """ + Enum class for api provider schema type. + """ + OPENAPI = "openapi" + SWAGGER = "swagger" + OPENAI_PLUGIN = "openai_plugin" + OPENAI_ACTIONS = "openai_actions" + + @classmethod + def value_of(cls, value: str) -> 'ApiProviderSchemaType': + """ + Get value of given mode. + + :param value: mode value + :return: mode + """ + for mode in cls: + if mode.value == value: + return mode + raise ValueError(f'invalid mode value {value}') + +class ApiProviderAuthType(Enum): + """ + Enum class for api provider auth type. + """ + NONE = "none" + API_KEY = "api_key" + + @classmethod + def value_of(cls, value: str) -> 'ApiProviderAuthType': + """ + Get value of given mode. + + :param value: mode value + :return: mode + """ + for mode in cls: + if mode.value == value: + return mode + raise ValueError(f'invalid mode value {value}') + +class ToolInvokeMessage(BaseModel): + class MessageType(Enum): + TEXT = "text" + IMAGE = "image" + LINK = "link" + BLOB = "blob" + IMAGE_LINK = "image_link" + + type: MessageType = MessageType.TEXT + """ + plain text, image url or link url + """ + message: Union[str, bytes] = None + meta: Dict[str, Any] = None + save_as: str = '' + +class ToolInvokeMessageBinary(BaseModel): + mimetype: str = Field(..., description="The mimetype of the binary") + url: str = Field(..., description="The url of the binary") + save_as: str = '' + +class ToolParamterOption(BaseModel): + value: str = Field(..., description="The value of the option") + label: I18nObject = Field(..., description="The label of the option") + +class ToolParamter(BaseModel): + class ToolParameterType(Enum): + STRING = "string" + NUMBER = "number" + BOOLEAN = "boolean" + SELECT = "select" + + class ToolParameterForm(Enum): + SCHEMA = "schema" # should be set while adding tool + FORM = "form" # should be set before invoking tool + LLM = "llm" # will be set by LLM + + name: str = Field(..., description="The name of the parameter") + label: I18nObject = Field(..., description="The label presented to the user") + human_description: I18nObject = Field(..., description="The description presented to the user") + type: ToolParameterType = Field(..., description="The type of the parameter") + form: ToolParameterForm = Field(..., description="The form of the parameter, schema/form/llm") + llm_description: Optional[str] = None + required: Optional[bool] = False + default: Optional[str] = None + min: Optional[Union[float, int]] = None + max: Optional[Union[float, int]] = None + options: Optional[List[ToolParamterOption]] = None + + @classmethod + def get_simple_instance(cls, + name: str, llm_description: str, type: ToolParameterType, + required: bool, options: Optional[List[str]] = None) -> 'ToolParamter': + """ + get a simple tool parameter + + :param name: the name of the parameter + :param llm_description: the description presented to the LLM + :param type: the type of the parameter + :param required: if the parameter is required + :param options: the options of the parameter + """ + # convert options to ToolParamterOption + if options: + options = [ToolParamterOption(value=option, label=I18nObject(en_US=option, zh_Hans=option)) for option in options] + return cls( + name=name, + label=I18nObject(en_US='', zh_Hans=''), + human_description=I18nObject(en_US='', zh_Hans=''), + type=type, + form=cls.ToolParameterForm.LLM, + llm_description=llm_description, + required=required, + options=options, + ) + +class ToolProviderIdentity(BaseModel): + author: str = Field(..., description="The author of the tool") + name: str = Field(..., description="The name of the tool") + description: I18nObject = Field(..., description="The description of the tool") + icon: str = Field(..., description="The icon of the tool") + label: I18nObject = Field(..., description="The label of the tool") + +class ToolDescription(BaseModel): + human: I18nObject = Field(..., description="The description presented to the user") + llm: str = Field(..., description="The description presented to the LLM") + +class ToolIdentity(BaseModel): + author: str = Field(..., description="The author of the tool") + name: str = Field(..., description="The name of the tool") + label: I18nObject = Field(..., description="The label of the tool") + +class ToolCredentialsOption(BaseModel): + value: str = Field(..., description="The value of the option") + label: I18nObject = Field(..., description="The label of the option") + +class ToolProviderCredentials(BaseModel): + class CredentialsType(Enum): + SECRET_INPUT = "secret-input" + TEXT_INPUT = "text-input" + SELECT = "select" + + @classmethod + def value_of(cls, value: str) -> "ToolProviderCredentials.CredentialsType": + """ + Get value of given mode. + + :param value: mode value + :return: mode + """ + for mode in cls: + if mode.value == value: + return mode + raise ValueError(f'invalid mode value {value}') + + @staticmethod + def defaut(value: str) -> str: + return "" + + name: str = Field(..., description="The name of the credentials") + type: CredentialsType = Field(..., description="The type of the credentials") + required: bool = False + default: Optional[str] = None + options: Optional[List[ToolCredentialsOption]] = None + label: Optional[I18nObject] = None + help: Optional[I18nObject] = None + url: Optional[str] = None + placeholder: Optional[I18nObject] = None + + def to_dict(self) -> dict: + return { + 'name': self.name, + 'type': self.type.value, + 'required': self.required, + 'default': self.default, + 'options': self.options, + 'help': self.help.to_dict() if self.help else None, + 'label': self.label.to_dict(), + 'url': self.url, + 'placeholder': self.placeholder.to_dict() if self.placeholder else None, + } + +class ToolRuntimeVariableType(Enum): + TEXT = "text" + IMAGE = "image" + +class ToolRuntimeVariable(BaseModel): + type: ToolRuntimeVariableType = Field(..., description="The type of the variable") + name: str = Field(..., description="The name of the variable") + position: int = Field(..., description="The position of the variable") + tool_name: str = Field(..., description="The name of the tool") + +class ToolRuntimeTextVariable(ToolRuntimeVariable): + value: str = Field(..., description="The value of the variable") + +class ToolRuntimeImageVariable(ToolRuntimeVariable): + value: str = Field(..., description="The path of the image") + +class ToolRuntimeVariablePool(BaseModel): + conversation_id: str = Field(..., description="The conversation id") + user_id: str = Field(..., description="The user id") + tenant_id: str = Field(..., description="The tenant id of assistant") + + pool: List[ToolRuntimeVariable] = Field(..., description="The pool of variables") + + def __init__(self, **data: Any): + pool = data.get('pool', []) + # convert pool into correct type + for index, variable in enumerate(pool): + if variable['type'] == ToolRuntimeVariableType.TEXT.value: + pool[index] = ToolRuntimeTextVariable(**variable) + elif variable['type'] == ToolRuntimeVariableType.IMAGE.value: + pool[index] = ToolRuntimeImageVariable(**variable) + super().__init__(**data) + + def dict(self) -> dict: + return { + 'conversation_id': self.conversation_id, + 'user_id': self.user_id, + 'tenant_id': self.tenant_id, + 'pool': [variable.dict() for variable in self.pool], + } + + def set_text(self, tool_name: str, name: str, value: str) -> None: + """ + set a text variable + """ + for variable in self.pool: + if variable.name == name: + if variable.type == ToolRuntimeVariableType.TEXT: + variable = cast(ToolRuntimeTextVariable, variable) + variable.value = value + return + + variable = ToolRuntimeTextVariable( + type=ToolRuntimeVariableType.TEXT, + name=name, + position=len(self.pool), + tool_name=tool_name, + value=value, + ) + + self.pool.append(variable) + + def set_file(self, tool_name: str, value: str, name: str = None) -> None: + """ + set an image variable + + :param tool_name: the name of the tool + :param value: the id of the file + """ + # check how many image variables are there + image_variable_count = 0 + for variable in self.pool: + if variable.type == ToolRuntimeVariableType.IMAGE: + image_variable_count += 1 + + if name is None: + name = f"file_{image_variable_count}" + + for variable in self.pool: + if variable.name == name: + if variable.type == ToolRuntimeVariableType.IMAGE: + variable = cast(ToolRuntimeImageVariable, variable) + variable.value = value + return + + variable = ToolRuntimeImageVariable( + type=ToolRuntimeVariableType.IMAGE, + name=name, + position=len(self.pool), + tool_name=tool_name, + value=value, + ) + + self.pool.append(variable) \ No newline at end of file diff --git a/api/core/tools/entities/user_entities.py b/api/core/tools/entities/user_entities.py new file mode 100644 index 000000000..ce4723f07 --- /dev/null +++ b/api/core/tools/entities/user_entities.py @@ -0,0 +1,48 @@ +from pydantic import BaseModel +from enum import Enum +from typing import List, Dict, Optional + +from core.tools.entities.common_entities import I18nObject +from core.tools.entities.tool_entities import ToolProviderCredentials +from core.tools.tool.tool import ToolParamter + +class UserToolProvider(BaseModel): + class ProviderType(Enum): + BUILTIN = "builtin" + APP = "app" + API = "api" + + id: str + author: str + name: str # identifier + description: I18nObject + icon: str + label: I18nObject # label + type: ProviderType + team_credentials: dict = None + is_team_authorization: bool = False + allow_delete: bool = True + + def to_dict(self) -> dict: + return { + 'id': self.id, + 'author': self.author, + 'name': self.name, + 'description': self.description.to_dict(), + 'icon': self.icon, + 'label': self.label.to_dict(), + 'type': self.type.value, + 'team_credentials': self.team_credentials, + 'is_team_authorization': self.is_team_authorization, + 'allow_delete': self.allow_delete + } + +class UserToolProviderCredentials(BaseModel): + credentails: Dict[str, ToolProviderCredentials] + +class UserTool(BaseModel): + author: str + name: str # identifier + label: I18nObject # label + description: I18nObject + parameters: Optional[List[ToolParamter]] \ No newline at end of file diff --git a/api/core/tools/errors.py b/api/core/tools/errors.py new file mode 100644 index 000000000..28fc241bb --- /dev/null +++ b/api/core/tools/errors.py @@ -0,0 +1,20 @@ +class ToolProviderNotFoundError(ValueError): + pass + +class ToolNotFoundError(ValueError): + pass + +class ToolParamterValidationError(ValueError): + pass + +class ToolProviderCredentialValidationError(ValueError): + pass + +class ToolNotSupportedError(ValueError): + pass + +class ToolInvokeError(ValueError): + pass + +class ToolApiSchemaError(ValueError): + pass \ No newline at end of file diff --git a/api/core/tools/model/errors.py b/api/core/tools/model/errors.py new file mode 100644 index 000000000..6e242b349 --- /dev/null +++ b/api/core/tools/model/errors.py @@ -0,0 +1,2 @@ +class InvokeModelError(Exception): + pass \ No newline at end of file diff --git a/api/core/tools/model/tool_model_manager.py b/api/core/tools/model/tool_model_manager.py new file mode 100644 index 000000000..0a8e13134 --- /dev/null +++ b/api/core/tools/model/tool_model_manager.py @@ -0,0 +1,174 @@ +""" + For some reason, model will be used in tools like WebScraperTool, WikipediaSearchTool etc. + + Therefore, a model manager is needed to list/invoke/validate models. +""" + +from core.model_runtime.entities.message_entities import PromptMessage +from core.model_runtime.entities.llm_entities import LLMResult +from core.model_runtime.entities.model_entities import ModelType +from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel, ModelPropertyKey +from core.model_runtime.errors.invoke import InvokeRateLimitError, InvokeBadRequestError, \ + InvokeConnectionError, InvokeAuthorizationError, InvokeServerUnavailableError +from core.model_runtime.utils.encoders import jsonable_encoder +from core.model_manager import ModelManager + +from core.tools.model.errors import InvokeModelError + +from extensions.ext_database import db + +from models.tools import ToolModelInvoke + +from typing import List, cast +import json + +class ToolModelManager: + @staticmethod + def get_max_llm_context_tokens( + tenant_id: str, + ) -> int: + """ + get max llm context tokens of the model + """ + model_manager = ModelManager() + model_instance = model_manager.get_default_model_instance( + tenant_id=tenant_id, model_type=ModelType.LLM, + ) + + if not model_instance: + raise InvokeModelError(f'Model not found') + + llm_model = cast(LargeLanguageModel, model_instance.model_type_instance) + schema = llm_model.get_model_schema(model_instance.model, model_instance.credentials) + + if not schema: + raise InvokeModelError(f'No model schema found') + + max_tokens = schema.model_properties.get(ModelPropertyKey.CONTEXT_SIZE, None) + if max_tokens is None: + return 2048 + + return max_tokens + + @staticmethod + def calculate_tokens( + tenant_id: str, + prompt_messages: List[PromptMessage] + ) -> int: + """ + calculate tokens from prompt messages and model parameters + """ + + # get model instance + model_manager = ModelManager() + model_instance = model_manager.get_default_model_instance( + tenant_id=tenant_id, model_type=ModelType.LLM + ) + + if not model_instance: + raise InvokeModelError(f'Model not found') + + llm_model = cast(LargeLanguageModel, model_instance.model_type_instance) + + # get tokens + tokens = llm_model.get_num_tokens(model_instance.model, model_instance.credentials, prompt_messages) + + return tokens + + @staticmethod + def invoke( + user_id: str, tenant_id: str, + tool_type: str, tool_name: str, + prompt_messages: List[PromptMessage] + ) -> LLMResult: + """ + invoke model with parameters in user's own context + + :param user_id: user id + :param tenant_id: tenant id, the tenant id of the creator of the tool + :param tool_provider: tool provider + :param tool_id: tool id + :param tool_name: tool name + :param provider: model provider + :param model: model name + :param model_parameters: model parameters + :param prompt_messages: prompt messages + :return: AssistantPromptMessage + """ + + # get model manager + model_manager = ModelManager() + # get model instance + model_instance = model_manager.get_default_model_instance( + tenant_id=tenant_id, model_type=ModelType.LLM, + ) + + llm_model = cast(LargeLanguageModel, model_instance.model_type_instance) + + # get model credentials + model_credentials = model_instance.credentials + + # get prompt tokens + prompt_tokens = llm_model.get_num_tokens(model_instance.model, model_credentials, prompt_messages) + + model_parameters = { + 'temperature': 0.8, + 'top_p': 0.8, + } + + # create tool model invoke + tool_model_invoke = ToolModelInvoke( + user_id=user_id, + tenant_id=tenant_id, + provider=model_instance.provider, + tool_type=tool_type, + tool_name=tool_name, + model_parameters=json.dumps(model_parameters), + prompt_messages=json.dumps(jsonable_encoder(prompt_messages)), + model_response='', + prompt_tokens=prompt_tokens, + answer_tokens=0, + answer_unit_price=0, + answer_price_unit=0, + provider_response_latency=0, + total_price=0, + currency='USD', + ) + + db.session.add(tool_model_invoke) + db.session.commit() + + try: + response: LLMResult = llm_model.invoke( + model=model_instance.model, + credentials=model_credentials, + prompt_messages=prompt_messages, + model_parameters=model_parameters, + tools=[], stop=[], stream=False, user=user_id, callbacks=[] + ) + except InvokeRateLimitError as e: + raise InvokeModelError(f'Invoke rate limit error: {e}') + except InvokeBadRequestError as e: + raise InvokeModelError(f'Invoke bad request error: {e}') + except InvokeConnectionError as e: + raise InvokeModelError(f'Invoke connection error: {e}') + except InvokeAuthorizationError as e: + raise InvokeModelError(f'Invoke authorization error') + except InvokeServerUnavailableError as e: + raise InvokeModelError(f'Invoke server unavailable error: {e}') + except Exception as e: + raise InvokeModelError(f'Invoke error: {e}') + + # update tool model invoke + tool_model_invoke.model_response = response.message.content + if response.usage: + tool_model_invoke.answer_tokens = response.usage.completion_tokens + tool_model_invoke.answer_unit_price = response.usage.completion_unit_price + tool_model_invoke.answer_price_unit = response.usage.completion_price_unit + tool_model_invoke.provider_response_latency = response.usage.latency + tool_model_invoke.total_price = response.usage.total_price + tool_model_invoke.currency = response.usage.currency + + db.session.commit() + + return response \ No newline at end of file diff --git a/api/core/tools/prompt/template.py b/api/core/tools/prompt/template.py new file mode 100644 index 000000000..3d3559227 --- /dev/null +++ b/api/core/tools/prompt/template.py @@ -0,0 +1,102 @@ +ENGLISH_REACT_COMPLETION_PROMPT_TEMPLATES = """Respond to the human as helpfully and accurately as possible. + +{{instruction}} + +You have access to the following tools: + +{{tools}} + +Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input). +Valid "action" values: "Final Answer" or {{tool_names}} + +Provide only ONE action per $JSON_BLOB, as shown: + +``` +{ + "action": $TOOL_NAME, + "action_input": $ACTION_INPUT +} +``` + +Follow this format: + +Question: input question to answer +Thought: consider previous and subsequent steps +Action: +``` +$JSON_BLOB +``` +Observation: action result +... (repeat Thought/Action/Observation N times) +Thought: I know what to respond +Action: +``` +{ + "action": "Final Answer", + "action_input": "Final response to human" +} +``` + +Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:. +Question: {{query}} +Thought: {{agent_scratchpad}}""" + +ENGLISH_REACT_COMPLETION_AGENT_SCRATCHPAD_TEMPLATES = """Observation: {{observation}} +Thought:""" + +ENGLISH_REACT_CHAT_PROMPT_TEMPLATES = """Respond to the human as helpfully and accurately as possible. + +{{instruction}} + +You have access to the following tools: + +{{tools}} + +Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input). +Valid "action" values: "Final Answer" or {{tool_names}} + +Provide only ONE action per $JSON_BLOB, as shown: + +``` +{ + "action": $TOOL_NAME, + "action_input": $ACTION_INPUT +} +``` + +Follow this format: + +Question: input question to answer +Thought: consider previous and subsequent steps +Action: +``` +$JSON_BLOB +``` +Observation: action result +... (repeat Thought/Action/Observation N times) +Thought: I know what to respond +Action: +``` +{ + "action": "Final Answer", + "action_input": "Final response to human" +} +``` + +Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:. +""" + +ENGLISH_REACT_CHAT_AGENT_SCRATCHPAD_TEMPLATES = "" + +REACT_PROMPT_TEMPLATES = { + 'english': { + 'chat': { + 'prompt': ENGLISH_REACT_CHAT_PROMPT_TEMPLATES, + 'agent_scratchpad': ENGLISH_REACT_CHAT_AGENT_SCRATCHPAD_TEMPLATES + }, + 'completion': { + 'prompt': ENGLISH_REACT_COMPLETION_PROMPT_TEMPLATES, + 'agent_scratchpad': ENGLISH_REACT_COMPLETION_AGENT_SCRATCHPAD_TEMPLATES + } + } +} \ No newline at end of file diff --git a/api/core/tools/provider/api_tool_provider.py b/api/core/tools/provider/api_tool_provider.py new file mode 100644 index 000000000..1d1f09f71 --- /dev/null +++ b/api/core/tools/provider/api_tool_provider.py @@ -0,0 +1,169 @@ +from typing import Any, Dict, List +from core.tools.entities.tool_entities import ToolProviderType, ApiProviderAuthType, ToolProviderCredentials, ToolCredentialsOption +from core.tools.entities.common_entities import I18nObject +from core.tools.entities.tool_bundle import ApiBasedToolBundle +from core.tools.tool.tool import Tool +from core.tools.tool.api_tool import ApiTool +from core.tools.provider.tool_provider import ToolProviderController + +from extensions.ext_database import db + +from models.tools import ApiToolProvider + +class ApiBasedToolProviderController(ToolProviderController): + @staticmethod + def from_db(db_provider: ApiToolProvider, auth_type: ApiProviderAuthType) -> 'ApiBasedToolProviderController': + credentials_schema = { + 'auth_type': ToolProviderCredentials( + name='auth_type', + required=True, + type=ToolProviderCredentials.CredentialsType.SELECT, + options=[ + ToolCredentialsOption(value='none', label=I18nObject(en_US='None', zh_Hans='无')), + ToolCredentialsOption(value='api_key', label=I18nObject(en_US='api_key', zh_Hans='api_key')) + ], + default='none', + help=I18nObject( + en_US='The auth type of the api provider', + zh_Hans='api provider 的认证类型' + ) + ) + } + if auth_type == ApiProviderAuthType.API_KEY: + credentials_schema = { + **credentials_schema, + 'api_key_header': ToolProviderCredentials( + name='api_key_header', + required=False, + default='api_key', + type=ToolProviderCredentials.CredentialsType.TEXT_INPUT, + help=I18nObject( + en_US='The header name of the api key', + zh_Hans='携带 api key 的 header 名称' + ) + ), + 'api_key_value': ToolProviderCredentials( + name='api_key_value', + required=True, + type=ToolProviderCredentials.CredentialsType.SECRET_INPUT, + help=I18nObject( + en_US='The api key', + zh_Hans='api key的值' + ) + ) + } + elif auth_type == ApiProviderAuthType.NONE: + pass + else: + raise ValueError(f'invalid auth type {auth_type}') + + return ApiBasedToolProviderController(**{ + 'identity': { + 'author': db_provider.user.name if db_provider.user_id and db_provider.user else '', + 'name': db_provider.name, + 'label': { + 'en_US': db_provider.name, + 'zh_Hans': db_provider.name + }, + 'description': { + 'en_US': db_provider.description, + 'zh_Hans': db_provider.description + }, + 'icon': db_provider.icon + }, + 'credentials_schema': credentials_schema + }) + + @property + def app_type(self) -> ToolProviderType: + return ToolProviderType.API_BASED + + def _validate_credentials(self, tool_name: str, credentials: Dict[str, Any]) -> None: + pass + + def validate_parameters(self, tool_name: str, tool_parameters: Dict[str, Any]) -> None: + pass + + def _parse_tool_bundle(self, tool_bundle: ApiBasedToolBundle) -> ApiTool: + """ + parse tool bundle to tool + + :param tool_bundle: the tool bundle + :return: the tool + """ + return ApiTool(**{ + 'api_bundle': tool_bundle, + 'identity' : { + 'author': tool_bundle.author, + 'name': tool_bundle.operation_id, + 'label': { + 'en_US': tool_bundle.operation_id, + 'zh_Hans': tool_bundle.operation_id + }, + 'icon': tool_bundle.icon if tool_bundle.icon else '' + }, + 'description': { + 'human': { + 'en_US': tool_bundle.summary or '', + 'zh_Hans': tool_bundle.summary or '' + }, + 'llm': tool_bundle.summary or '' + }, + 'parameters' : tool_bundle.parameters if tool_bundle.parameters else [], + }) + + def load_bundled_tools(self, tools: List[ApiBasedToolBundle]) -> List[ApiTool]: + """ + load bundled tools + + :param tools: the bundled tools + :return: the tools + """ + self.tools = [self._parse_tool_bundle(tool) for tool in tools] + + return self.tools + + def get_tools(self, user_id: str, tanent_id: str) -> List[ApiTool]: + """ + fetch tools from database + + :param user_id: the user id + :param tanent_id: the tanent id + :return: the tools + """ + if self.tools is not None: + return self.tools + + tools: List[Tool] = [] + + # get tanent api providers + db_providers: List[ApiToolProvider] = db.session.query(ApiToolProvider).filter( + ApiToolProvider.tenant_id == tanent_id, + ApiToolProvider.name == self.identity.name + ).all() + + if db_providers and len(db_providers) != 0: + for db_provider in db_providers: + for tool in db_provider.tools: + assistant_tool = self._parse_tool_bundle(tool) + assistant_tool.is_team_authorization = True + tools.append(assistant_tool) + + self.tools = tools + return tools + + def get_tool(self, tool_name: str) -> ApiTool: + """ + get tool by name + + :param tool_name: the name of the tool + :return: the tool + """ + if self.tools is None: + self.get_tools() + + for tool in self.tools: + if tool.identity.name == tool_name: + return tool + + raise ValueError(f'tool {tool_name} not found') \ No newline at end of file diff --git a/api/core/tools/provider/app_tool_provider.py b/api/core/tools/provider/app_tool_provider.py new file mode 100644 index 000000000..20f6b5573 --- /dev/null +++ b/api/core/tools/provider/app_tool_provider.py @@ -0,0 +1,116 @@ +from typing import Any, Dict, List +from core.tools.entities.tool_entities import ToolProviderType, ToolParamter, ToolParamterOption +from core.tools.tool.tool import Tool +from core.tools.entities.common_entities import I18nObject +from core.tools.provider.tool_provider import ToolProviderController + +from extensions.ext_database import db +from models.tools import PublishedAppTool +from models.model import App, AppModelConfig + +import logging + +logger = logging.getLogger(__name__) + +class AppBasedToolProviderEntity(ToolProviderController): + @property + def app_type(self) -> ToolProviderType: + return ToolProviderType.APP_BASED + + def _validate_credentials(self, tool_name: str, credentials: Dict[str, Any]) -> None: + pass + + def validate_parameters(self, tool_name: str, tool_parameters: Dict[str, Any]) -> None: + pass + + def get_tools(self, user_id: str) -> List[Tool]: + db_tools: List[PublishedAppTool] = db.session.query(PublishedAppTool).filter( + PublishedAppTool.user_id == user_id, + ).all() + + if not db_tools or len(db_tools) == 0: + return [] + + tools: List[Tool] = [] + + for db_tool in db_tools: + tool = { + 'identity': { + 'author': db_tool.author, + 'name': db_tool.tool_name, + 'label': { + 'en_US': db_tool.tool_name, + 'zh_Hans': db_tool.tool_name + }, + 'icon': '' + }, + 'description': { + 'human': { + 'en_US': db_tool.description_i18n.en_US, + 'zh_Hans': db_tool.description_i18n.zh_Hans + }, + 'llm': db_tool.llm_description + }, + 'parameters': [] + } + # get app from db + app: App = db_tool.app + + if not app: + logger.error(f"app {db_tool.app_id} not found") + continue + + app_model_config: AppModelConfig = app.app_model_config + user_input_form_list = app_model_config.user_input_form_list + for input_form in user_input_form_list: + # get type + form_type = input_form.keys()[0] + default = input_form[form_type]['default'] + required = input_form[form_type]['required'] + label = input_form[form_type]['label'] + variable_name = input_form[form_type]['variable_name'] + options = input_form[form_type].get('options', []) + if form_type == 'paragraph' or form_type == 'text-input': + tool['parameters'].append(ToolParamter( + name=variable_name, + label=I18nObject( + en_US=label, + zh_Hans=label + ), + human_description=I18nObject( + en_US=label, + zh_Hans=label + ), + llm_description=label, + form=ToolParamter.ToolParameterForm.FORM, + type=ToolParamter.ToolParameterType.STRING, + required=required, + default=default + )) + elif form_type == 'select': + tool['parameters'].append(ToolParamter( + name=variable_name, + label=I18nObject( + en_US=label, + zh_Hans=label + ), + human_description=I18nObject( + en_US=label, + zh_Hans=label + ), + llm_description=label, + form=ToolParamter.ToolParameterForm.FORM, + type=ToolParamter.ToolParameterType.SELECT, + required=required, + default=default, + options=[ToolParamterOption( + value=option, + label=I18nObject( + en_US=option, + zh_Hans=option + ) + ) for option in options] + )) + + tools.append(Tool(**tool)) + return tools \ No newline at end of file diff --git a/api/core/tools/provider/builtin/__init__.py b/api/core/tools/provider/builtin/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/core/tools/provider/builtin/_positions.py b/api/core/tools/provider/builtin/_positions.py new file mode 100644 index 000000000..b7c2b8018 --- /dev/null +++ b/api/core/tools/provider/builtin/_positions.py @@ -0,0 +1,26 @@ +from core.tools.entities.user_entities import UserToolProvider +from typing import List + +position = { + 'google': 1, + 'wikipedia': 2, + 'dalle': 3, + 'webscraper': 4, + 'wolframalpha': 5, + 'chart': 6, + 'time': 7, + 'yahoo': 8, + 'stablediffusion': 9, + 'vectorizer': 10, + 'youtube': 11, +} + +class BuiltinToolProviderSort: + @staticmethod + def sort(providers: List[UserToolProvider]) -> List[UserToolProvider]: + def sort_compare(provider: UserToolProvider) -> int: + return position.get(provider.name, 10000) + + sorted_providers = sorted(providers, key=sort_compare) + + return sorted_providers \ No newline at end of file diff --git a/api/core/tools/provider/builtin/chart/_assets/icon.png b/api/core/tools/provider/builtin/chart/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..878e56a0512c31735cc94480cef9b8fa5dfcc7fd GIT binary patch literal 1363 zcmV-Z1+4msP)@~0drDELIAGL9O(c600d`2O+f$vv5yPZ%b}MY?$!^0(ngoeR2q9r8kU$C`L_-DtfaD*9CP;uHKKjH23JN5$ zO@wH&siIUi)k2y$o9xEPdgkUHCytc)wtdgs8}0i@QMBXn%<6sS+!@~)?;!#J0I*+C zG$-9||Ip68MmGxRXie)it!i!3`Vj30lo~1>4b1ym5?c5a+MP{ zE+hQKUK))%WlB{&I^(BTW)yh0pLXB!!n1Fb!iGKEuKAGJZ{Je`(>f_^a3UNDA)+ z$CYCQE!I$tE=K{)v zarWn1)+G28KI2qC*)aH@4GF%5&o~n>YZ!}4@G*SGiGX>-m{)?Y;WL#BSTu}TCHNdZ zQ>g%3VU(5Nd-zPEUf+CYOXN3_2xGF%kIgopPv0ivTljzezWP|^l~jP#kyum-J|Fp0 z#05wX19=i8_GcSW0acB`WhD3*J|iZe>Jwm|1Yg5v!~`69Wx4V(I88!-u;*>~jMyEq zm6hbCt2h#Q+h@MpesnWO@@|$5#46zGwa1?%sCpRS;C&CD5vzddqa1uB4u=t4`sZ$` z@LSCq9eHgz^Yz<1nlAl4B3o3wzc`{d z9PjQ4x0=P%%FUL&d%{)kFAg3}bPNPI1_B%d0gizH$3TE%AiyyY;1~#S3S3V5l#RJ_iM#q0RGKU-i3ats7G z1_B%d0gizH$3TE%AiyyY;1~#SjM!Afx!-n37d%jQ{=&`^`#xJ#_9Z>=04HD41KB`; zV^aQfv6`zP87M$ujHpOaXi@;6{{?FhA2~o_W26bEhIEWfKJNLBi}z zGBeo~^%O=!X927>bY^%%d% None: + try: + LinearChartTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "data": "1,3,5,7,9,2,4,6,8,10", + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/chart/chart.yaml b/api/core/tools/provider/builtin/chart/chart.yaml new file mode 100644 index 000000000..9e953ec32 --- /dev/null +++ b/api/core/tools/provider/builtin/chart/chart.yaml @@ -0,0 +1,11 @@ +identity: + author: Dify + name: chart + label: + en_US: ChartGenerator + zh_Hans: 图表生成 + description: + en_US: Chart Generator is a tool for generating statistical charts like bar chart, line chart, pie chart, etc. + zh_Hans: 图表生成是一个用于生成可视化图表的工具,你可以通过它来生成柱状图、折线图、饼图等各类图表 + icon: icon.png +credentails_for_provider: diff --git a/api/core/tools/provider/builtin/chart/tools/bar.py b/api/core/tools/provider/builtin/chart/tools/bar.py new file mode 100644 index 000000000..fff60c54d --- /dev/null +++ b/api/core/tools/provider/builtin/chart/tools/bar.py @@ -0,0 +1,47 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage +import matplotlib.pyplot as plt +import io + +from typing import Any, Dict, List, Union + +class BarChartTool(BuiltinTool): + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + data = tool_paramters.get('data', '') + if not data: + return self.create_text_message('Please input data') + data = data.split(';') + + # if all data is int, convert to int + if all([i.isdigit() for i in data]): + data = [int(i) for i in data] + else: + data = [float(i) for i in data] + + axis = tool_paramters.get('x_axis', None) or None + if axis: + axis = axis.split(';') + if len(axis) != len(data): + axis = None + + flg, ax = plt.subplots(figsize=(10, 8)) + + if axis: + axis = [label[:10] + '...' if len(label) > 10 else label for label in axis] + ax.set_xticklabels(axis, rotation=45, ha='right') + ax.bar(axis, data) + else: + ax.bar(range(len(data)), data) + + buf = io.BytesIO() + flg.savefig(buf, format='png') + buf.seek(0) + plt.close(flg) + + return [ + self.create_text_message('the bar chart is saved as an image.'), + self.create_blob_message(blob=buf.read(), + meta={'mime_type': 'image/png'}) + ] + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/chart/tools/bar.yaml b/api/core/tools/provider/builtin/chart/tools/bar.yaml new file mode 100644 index 000000000..9e6787e93 --- /dev/null +++ b/api/core/tools/provider/builtin/chart/tools/bar.yaml @@ -0,0 +1,35 @@ +identity: + name: bar_chart + author: Dify + label: + en_US: Bar Chart + zh_Hans: 柱状图 + icon: icon.svg +description: + human: + en_US: Bar chart + zh_Hans: 柱状图 + llm: generate a bar chart with input data +parameters: + - name: data + type: string + required: true + label: + en_US: data + zh_Hans: 数据 + human_description: + en_US: data for generating bar chart + zh_Hans: 用于生成柱状图的数据 + llm_description: data for generating bar chart, data should be a string contains a list of numbers like "1;2;3;4;5" + form: llm + - name: x_axis + type: string + required: false + label: + en_US: X Axis + zh_Hans: x 轴 + human_description: + en_US: X axis for bar chart + zh_Hans: 柱状图的 x 轴 + llm_description: x axis for bar chart, x axis should be a string contains a list of texts like "a;b;c;1;2" in order to match the data + form: llm diff --git a/api/core/tools/provider/builtin/chart/tools/line.py b/api/core/tools/provider/builtin/chart/tools/line.py new file mode 100644 index 000000000..2b0a44250 --- /dev/null +++ b/api/core/tools/provider/builtin/chart/tools/line.py @@ -0,0 +1,49 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage +import matplotlib.pyplot as plt +import io + +from typing import Any, Dict, List, Union + +class LinearChartTool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + data = tool_paramters.get('data', '') + if not data: + return self.create_text_message('Please input data') + data = data.split(';') + + axis = tool_paramters.get('x_axis', None) or None + if axis: + axis = axis.split(';') + if len(axis) != len(data): + axis = None + + # if all data is int, convert to int + if all([i.isdigit() for i in data]): + data = [int(i) for i in data] + else: + data = [float(i) for i in data] + + flg, ax = plt.subplots(figsize=(10, 8)) + + if axis: + axis = [label[:10] + '...' if len(label) > 10 else label for label in axis] + ax.set_xticklabels(axis, rotation=45, ha='right') + ax.plot(axis, data) + else: + ax.plot(data) + + buf = io.BytesIO() + flg.savefig(buf, format='png') + buf.seek(0) + plt.close(flg) + + return [ + self.create_text_message('the linear chart is saved as an image.'), + self.create_blob_message(blob=buf.read(), + meta={'mime_type': 'image/png'}) + ] + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/chart/tools/line.yaml b/api/core/tools/provider/builtin/chart/tools/line.yaml new file mode 100644 index 000000000..a4eb7affe --- /dev/null +++ b/api/core/tools/provider/builtin/chart/tools/line.yaml @@ -0,0 +1,35 @@ +identity: + name: line_chart + author: Dify + label: + en_US: Linear Chart + zh_Hans: 线性图表 + icon: icon.svg +description: + human: + en_US: linear chart + zh_Hans: 线性图表 + llm: generate a linear chart with input data +parameters: + - name: data + type: string + required: true + label: + en_US: data + zh_Hans: 数据 + human_description: + en_US: data for generating linear chart + zh_Hans: 用于生成线性图表的数据 + llm_description: data for generating linear chart, data should be a string contains a list of numbers like "1;2;3;4;5" + form: llm + - name: x_axis + type: string + required: false + label: + en_US: X Axis + zh_Hans: x 轴 + human_description: + en_US: X axis for linear chart + zh_Hans: 线性图表的 x 轴 + llm_description: x axis for linear chart, x axis should be a string contains a list of texts like "a;b;c;1;2" in order to match the data + form: llm diff --git a/api/core/tools/provider/builtin/chart/tools/pie.py b/api/core/tools/provider/builtin/chart/tools/pie.py new file mode 100644 index 000000000..5fec67df1 --- /dev/null +++ b/api/core/tools/provider/builtin/chart/tools/pie.py @@ -0,0 +1,46 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage +import matplotlib.pyplot as plt +import io + +from typing import Any, Dict, List, Union + +class PieChartTool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + data = tool_paramters.get('data', '') + if not data: + return self.create_text_message('Please input data') + data = data.split(';') + categories = tool_paramters.get('categories', None) or None + + # if all data is int, convert to int + if all([i.isdigit() for i in data]): + data = [int(i) for i in data] + else: + data = [float(i) for i in data] + + flg, ax = plt.subplots() + + if categories: + categories = categories.split(';') + if len(categories) != len(data): + categories = None + + if categories: + ax.pie(data, labels=categories) + else: + ax.pie(data) + + buf = io.BytesIO() + flg.savefig(buf, format='png') + buf.seek(0) + plt.close(flg) + + return [ + self.create_text_message('the pie chart is saved as an image.'), + self.create_blob_message(blob=buf.read(), + meta={'mime_type': 'image/png'}) + ] \ No newline at end of file diff --git a/api/core/tools/provider/builtin/chart/tools/pie.yaml b/api/core/tools/provider/builtin/chart/tools/pie.yaml new file mode 100644 index 000000000..2e3506d20 --- /dev/null +++ b/api/core/tools/provider/builtin/chart/tools/pie.yaml @@ -0,0 +1,35 @@ +identity: + name: pie_chart + author: Dify + label: + en_US: Pie Chart + zh_Hans: 饼图 + icon: icon.svg +description: + human: + en_US: Pie chart + zh_Hans: 饼图 + llm: generate a pie chart with input data +parameters: + - name: data + type: string + required: true + label: + en_US: data + zh_Hans: 数据 + human_description: + en_US: data for generating pie chart + zh_Hans: 用于生成饼图的数据 + llm_description: data for generating pie chart, data should be a string contains a list of numbers like "1;2;3;4;5" + form: llm + - name: categories + type: string + required: true + label: + en_US: Categories + zh_Hans: 分类 + human_description: + en_US: Categories for pie chart + zh_Hans: 饼图的分类 + llm_description: categories for pie chart, categories should be a string contains a list of texts like "a;b;c;1;2" in order to match the data, each category should be split by ";" + form: llm diff --git a/api/core/tools/provider/builtin/dalle/__init__.py b/api/core/tools/provider/builtin/dalle/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/core/tools/provider/builtin/dalle/_assets/icon.png b/api/core/tools/provider/builtin/dalle/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5155a73059ed5590099f285324a68a6437b0458e GIT binary patch literal 156474 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 Z*92R|Jvv!ULn#2aG*q;eEB~_y`X9!4)eHat literal 0 HcmV?d00001 diff --git a/api/core/tools/provider/builtin/dalle/dalle.py b/api/core/tools/provider/builtin/dalle/dalle.py new file mode 100644 index 000000000..b8dc0b5b8 --- /dev/null +++ b/api/core/tools/provider/builtin/dalle/dalle.py @@ -0,0 +1,23 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.provider.builtin.dalle.tools.dalle2 import DallE2Tool +from core.tools.errors import ToolProviderCredentialValidationError + +from typing import Any, Dict + +class DALLEProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + DallE2Tool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "prompt": "cute girl, blue eyes, white hair, anime style", + "size": "small", + "n": 1 + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/dalle/dalle.yaml b/api/core/tools/provider/builtin/dalle/dalle.yaml new file mode 100644 index 000000000..54508ff80 --- /dev/null +++ b/api/core/tools/provider/builtin/dalle/dalle.yaml @@ -0,0 +1,47 @@ +identity: + author: Dify + name: dalle + label: + en_US: DALL-E + zh_Hans: DALL-E 绘画 + description: + en_US: DALL-E art + zh_Hans: DALL-E 绘画 + icon: icon.png +credentails_for_provider: + openai_api_key: + type: secret-input + required: true + label: + en_US: OpenAI API key + zh_Hans: OpenAI API key + help: + en_US: Please input your OpenAI API key + zh_Hans: 请输入你的 OpenAI API key + placeholder: + en_US: Please input your OpenAI API key + zh_Hans: 请输入你的 OpenAI API key + openai_organizaion_id: + type: text-input + required: false + label: + en_US: OpenAI organization ID + zh_Hans: OpenAI organization ID + help: + en_US: Please input your OpenAI organization ID + zh_Hans: 请输入你的 OpenAI organization ID + placeholder: + en_US: Please input your OpenAI organization ID + zh_Hans: 请输入你的 OpenAI organization ID + openai_base_url: + type: text-input + required: false + label: + en_US: OpenAI base URL + zh_Hans: OpenAI base URL + help: + en_US: Please input your OpenAI base URL + zh_Hans: 请输入你的 OpenAI base URL + placeholder: + en_US: Please input your OpenAI base URL + zh_Hans: 请输入你的 OpenAI base URL diff --git a/api/core/tools/provider/builtin/dalle/tools/dalle2.py b/api/core/tools/provider/builtin/dalle/tools/dalle2.py new file mode 100644 index 000000000..2a18e05ab --- /dev/null +++ b/api/core/tools/provider/builtin/dalle/tools/dalle2.py @@ -0,0 +1,66 @@ +from typing import Any, Dict, List, Union +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + +from base64 import b64decode +from os.path import join + +from openai import OpenAI + +class DallE2Tool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + openai_organization = self.runtime.credentials.get('openai_organizaion_id', None) + if not openai_organization: + openai_organization = None + openai_base_url = self.runtime.credentials.get('openai_base_url', None) + if not openai_base_url: + openai_base_url = None + else: + openai_base_url = join(openai_base_url, 'v1') + + client = OpenAI( + api_key=self.runtime.credentials['openai_api_key'], + base_url=openai_base_url, + organization=openai_organization + ) + + SIZE_MAPPING = { + 'small': '256x256', + 'medium': '512x512', + 'large': '1024x1024', + } + + # prompt + prompt = tool_paramters.get('prompt', '') + if not prompt: + return self.create_text_message('Please input prompt') + + # get size + size = SIZE_MAPPING[tool_paramters.get('size', 'large')] + + # get n + n = tool_paramters.get('n', 1) + + # call openapi dalle2 + response = client.images.generate( + prompt=prompt, + model='dall-e-2', + size=size, + n=n, + response_format='b64_json' + ) + + result = [] + + for image in response.data: + result.append(self.create_blob_message(blob=b64decode(image.b64_json), + meta={ 'mime_type': 'image/png' }, + save_as=self.VARIABLE_KEY.IMAGE.value)) + + return result diff --git a/api/core/tools/provider/builtin/dalle/tools/dalle2.yaml b/api/core/tools/provider/builtin/dalle/tools/dalle2.yaml new file mode 100644 index 000000000..ebcaf02eb --- /dev/null +++ b/api/core/tools/provider/builtin/dalle/tools/dalle2.yaml @@ -0,0 +1,63 @@ +identity: + name: dalle2 + author: Dify + label: + en_US: DALL-E 2 + zh_Hans: DALL-E 2 绘画 + description: + en_US: DALL-E 2 is a powerful drawing tool that can draw the image you want based on your prompt + zh_Hans: DALL-E 2 是一个强大的绘画工具,它可以根据您的提示词绘制出您想要的图像 +description: + human: + en_US: DALL-E is a text to image tool + zh_Hans: DALL-E 是一个文本到图像的工具 + llm: DALL-E is a tool used to generate images from text +parameters: + - name: prompt + type: string + required: true + label: + en_US: Prompt + zh_Hans: 提示词 + human_description: + en_US: Image prompt, you can check the official documentation of DallE 2 + zh_Hans: 图像提示词,您可以查看DallE 2 的官方文档 + llm_description: Image prompt of DallE 2, you should describe the image you want to generate as a list of words as possible as detailed + form: llm + - name: size + type: select + required: true + human_description: + en_US: used for selecting the image size + zh_Hans: 用于选择图像大小 + label: + en_US: Image size + zh_Hans: 图像大小 + form: form + options: + - value: small + label: + en_US: Small(256x256) + zh_Hans: 小(256x256) + - value: medium + label: + en_US: Medium(512x512) + zh_Hans: 中(512x512) + - value: large + label: + en_US: Large(1024x1024) + zh_Hans: 大(1024x1024) + default: large + - name: n + type: number + required: true + human_description: + en_US: used for selecting the number of images + zh_Hans: 用于选择图像数量 + label: + en_US: Number of images + zh_Hans: 图像数量 + form: form + default: 1 + min: 1 + max: 10 diff --git a/api/core/tools/provider/builtin/dalle/tools/dalle3.py b/api/core/tools/provider/builtin/dalle/tools/dalle3.py new file mode 100644 index 000000000..0b2d8df0e --- /dev/null +++ b/api/core/tools/provider/builtin/dalle/tools/dalle3.py @@ -0,0 +1,74 @@ +from typing import Any, Dict, List, Union +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + +from base64 import b64decode +from os.path import join + +from openai import OpenAI + +class DallE3Tool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + openai_organization = self.runtime.credentials.get('openai_organizaion_id', None) + if not openai_organization: + openai_organization = None + openai_base_url = self.runtime.credentials.get('openai_base_url', None) + if not openai_base_url: + openai_base_url = None + else: + openai_base_url = join(openai_base_url, 'v1') + + client = OpenAI( + api_key=self.runtime.credentials['openai_api_key'], + base_url=openai_base_url, + organization=openai_organization + ) + + SIZE_MAPPING = { + 'square': '1024x1024', + 'vertical': '1024x1792', + 'horizontal': '1792x1024', + } + + # prompt + prompt = tool_paramters.get('prompt', '') + if not prompt: + return self.create_text_message('Please input prompt') + # get size + size = SIZE_MAPPING[tool_paramters.get('size', 'square')] + # get n + n = tool_paramters.get('n', 1) + # get quality + quality = tool_paramters.get('quality', 'standard') + if quality not in ['standard', 'hd']: + return self.create_text_message('Invalid quality') + # get style + style = tool_paramters.get('style', 'vivid') + if style not in ['natural', 'vivid']: + return self.create_text_message('Invalid style') + + # call openapi dalle3 + response = client.images.generate( + prompt=prompt, + model='dall-e-3', + size=size, + n=n, + style=style, + quality=quality, + response_format='b64_json' + ) + + result = [] + + for image in response.data: + result.append(self.create_blob_message(blob=b64decode(image.b64_json), + meta={ 'mime_type': 'image/png' }, + save_as=self.VARIABLE_KEY.IMAGE.value)) + + return result diff --git a/api/core/tools/provider/builtin/dalle/tools/dalle3.yaml b/api/core/tools/provider/builtin/dalle/tools/dalle3.yaml new file mode 100644 index 000000000..0497a3274 --- /dev/null +++ b/api/core/tools/provider/builtin/dalle/tools/dalle3.yaml @@ -0,0 +1,103 @@ +identity: + name: dalle3 + author: Dify + label: + en_US: DALL-E 3 + zh_Hans: DALL-E 3 绘画 + description: + en_US: DALL-E 3 is a powerful drawing tool that can draw the image you want based on your prompt, compared to DallE 2, DallE 3 has stronger drawing ability, but it will consume more resources + zh_Hans: DALL-E 3 是一个强大的绘画工具,它可以根据您的提示词绘制出您想要的图像,相比于DallE 2, DallE 3拥有更强的绘画能力,但会消耗更多的资源 +description: + human: + en_US: DALL-E is a text to image tool + zh_Hans: DALL-E 是一个文本到图像的工具 + llm: DALL-E is a tool used to generate images from text +parameters: + - name: prompt + type: string + required: true + label: + en_US: Prompt + zh_Hans: 提示词 + human_description: + en_US: Image prompt, you can check the official documentation of DallE 3 + zh_Hans: 图像提示词,您可以查看DallE 3 的官方文档 + llm_description: Image prompt of DallE 3, you should describe the image you want to generate as a list of words as possible as detailed + form: llm + - name: size + type: select + required: true + human_description: + en_US: selecting the image size + zh_Hans: 选择图像大小 + label: + en_US: Image size + zh_Hans: 图像大小 + form: form + options: + - value: square + label: + en_US: Squre(1024x1024) + zh_Hans: 方(1024x1024) + - value: vertical + label: + en_US: Vertical(1024x1792) + zh_Hans: 竖屏(1024x1792) + - value: horizontal + label: + en_US: Horizontal(1792x1024) + zh_Hans: 横屏(1792x1024) + default: square + - name: n + type: number + required: true + human_description: + en_US: selecting the number of images + zh_Hans: 选择图像数量 + label: + en_US: Number of images + zh_Hans: 图像数量 + form: form + min: 1 + max: 1 + default: 1 + - name: quality + type: select + required: true + human_description: + en_US: selecting the image quality + zh_Hans: 选择图像质量 + label: + en_US: Image quality + zh_Hans: 图像质量 + form: form + options: + - value: standard + label: + en_US: Standard + zh_Hans: 标准 + - value: hd + label: + en_US: HD + zh_Hans: 高清 + default: standard + - name: style + type: select + required: true + human_description: + en_US: selecting the image style + zh_Hans: 选择图像风格 + label: + en_US: Image style + zh_Hans: 图像风格 + form: form + options: + - value: vivid + label: + en_US: Vivid + zh_Hans: 生动 + - value: natural + label: + en_US: Natural + zh_Hans: 自然 + default: vivid diff --git a/api/core/tools/provider/builtin/google/_assets/icon.svg b/api/core/tools/provider/builtin/google/_assets/icon.svg new file mode 100644 index 000000000..bebbf52d3 --- /dev/null +++ b/api/core/tools/provider/builtin/google/_assets/icon.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/google/google.py b/api/core/tools/provider/builtin/google/google.py new file mode 100644 index 000000000..9ce52f470 --- /dev/null +++ b/api/core/tools/provider/builtin/google/google.py @@ -0,0 +1,23 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.google.tools.google_search import GoogleSearchTool + +from typing import Any, Dict, List + +class GoogleProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + GoogleSearchTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "query": "test", + "result_type": "link" + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/google/google.yaml b/api/core/tools/provider/builtin/google/google.yaml new file mode 100644 index 000000000..3c0dd63a4 --- /dev/null +++ b/api/core/tools/provider/builtin/google/google.yaml @@ -0,0 +1,24 @@ +identity: + author: Dify + name: google + label: + en_US: Google + zh_Hans: Google + description: + en_US: Google + zh_Hans: GoogleSearch + icon: icon.svg +credentails_for_provider: + serpapi_api_key: + type: secret-input + required: true + label: + en_US: SerpApi API key + zh_Hans: SerpApi API key + placeholder: + en_US: Please input your SerpApi API key + zh_Hans: 请输入你的 SerpApi API key + help: + en_US: Get your SerpApi API key from SerpApi + zh_Hans: 从 SerpApi 获取您的 SerpApi API key + url: https://serpapi.com/manage-api-key diff --git a/api/core/tools/provider/builtin/google/tools/google_search.py b/api/core/tools/provider/builtin/google/tools/google_search.py new file mode 100644 index 000000000..c902f1477 --- /dev/null +++ b/api/core/tools/provider/builtin/google/tools/google_search.py @@ -0,0 +1,163 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage + +from typing import Any, Dict, List, Union + +import os +import sys + +from serpapi import GoogleSearch + +class HiddenPrints: + """Context manager to hide prints.""" + + def __enter__(self) -> None: + """Open file to pipe stdout to.""" + self._original_stdout = sys.stdout + sys.stdout = open(os.devnull, "w") + + def __exit__(self, *_: Any) -> None: + """Close file that stdout was piped to.""" + sys.stdout.close() + sys.stdout = self._original_stdout + + +class SerpAPI: + """ + SerpAPI tool provider. + """ + + search_engine: Any #: :meta private: + serpapi_api_key: str = None + + def __init__(self, api_key: str) -> None: + """Initialize SerpAPI tool provider.""" + self.serpapi_api_key = api_key + self.search_engine = GoogleSearch + + def run(self, query: str, **kwargs: Any) -> str: + """Run query through SerpAPI and parse result.""" + typ = kwargs.get("result_type", "text") + return self._process_response(self.results(query), typ=typ) + + def results(self, query: str) -> dict: + """Run query through SerpAPI and return the raw result.""" + params = self.get_params(query) + with HiddenPrints(): + search = self.search_engine(params) + res = search.get_dict() + return res + + def get_params(self, query: str) -> Dict[str, str]: + """Get parameters for SerpAPI.""" + _params = { + "api_key": self.serpapi_api_key, + "q": query, + } + params = { + "engine": "google", + "google_domain": "google.com", + "gl": "us", + "hl": "en", + **_params + } + return params + + @staticmethod + def _process_response(res: dict, typ: str) -> str: + """Process response from SerpAPI.""" + if "error" in res.keys(): + raise ValueError(f"Got error from SerpAPI: {res['error']}") + + if typ == "text": + if "answer_box" in res.keys() and type(res["answer_box"]) == list: + res["answer_box"] = res["answer_box"][0] + if "answer_box" in res.keys() and "answer" in res["answer_box"].keys(): + toret = res["answer_box"]["answer"] + elif "answer_box" in res.keys() and "snippet" in res["answer_box"].keys(): + toret = res["answer_box"]["snippet"] + elif ( + "answer_box" in res.keys() + and "snippet_highlighted_words" in res["answer_box"].keys() + ): + toret = res["answer_box"]["snippet_highlighted_words"][0] + elif ( + "sports_results" in res.keys() + and "game_spotlight" in res["sports_results"].keys() + ): + toret = res["sports_results"]["game_spotlight"] + elif ( + "shopping_results" in res.keys() + and "title" in res["shopping_results"][0].keys() + ): + toret = res["shopping_results"][:3] + elif ( + "knowledge_graph" in res.keys() + and "description" in res["knowledge_graph"].keys() + ): + toret = res["knowledge_graph"]["description"] + elif "snippet" in res["organic_results"][0].keys(): + toret = res["organic_results"][0]["snippet"] + elif "link" in res["organic_results"][0].keys(): + toret = res["organic_results"][0]["link"] + elif ( + "images_results" in res.keys() + and "thumbnail" in res["images_results"][0].keys() + ): + thumbnails = [item["thumbnail"] for item in res["images_results"][:10]] + toret = thumbnails + else: + toret = "No good search result found" + elif typ == "link": + if "knowledge_graph" in res.keys() and "title" in res["knowledge_graph"].keys() \ + and "description_link" in res["knowledge_graph"].keys(): + toret = res["knowledge_graph"]["description_link"] + elif "knowledge_graph" in res.keys() and "see_results_about" in res["knowledge_graph"].keys() \ + and len(res["knowledge_graph"]["see_results_about"]) > 0: + see_result_about = res["knowledge_graph"]["see_results_about"] + toret = "" + for item in see_result_about: + if "name" not in item.keys() or "link" not in item.keys(): + continue + toret += f"[{item['name']}]({item['link']})\n" + elif "organic_results" in res.keys() and len(res["organic_results"]) > 0: + organic_results = res["organic_results"] + toret = "" + for item in organic_results: + if "title" not in item.keys() or "link" not in item.keys(): + continue + toret += f"[{item['title']}]({item['link']})\n" + elif "related_questions" in res.keys() and len(res["related_questions"]) > 0: + related_questions = res["related_questions"] + toret = "" + for item in related_questions: + if "question" not in item.keys() or "link" not in item.keys(): + continue + toret += f"[{item['question']}]({item['link']})\n" + elif "related_searches" in res.keys() and len(res["related_searches"]) > 0: + related_searches = res["related_searches"] + toret = "" + for item in related_searches: + if "query" not in item.keys() or "link" not in item.keys(): + continue + toret += f"[{item['query']}]({item['link']})\n" + else: + toret = "No good search result found" + return toret + +class GoogleSearchTool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + query = tool_paramters['query'] + result_type = tool_paramters['result_type'] + api_key = self.runtime.credentials['serpapi_api_key'] + result = SerpAPI(api_key).run(query, result_type=result_type) + if result_type == 'text': + return self.create_text_message(text=result) + return self.create_link_message(link=result) + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/google/tools/google_search.yaml b/api/core/tools/provider/builtin/google/tools/google_search.yaml new file mode 100644 index 000000000..f3b2a96a2 --- /dev/null +++ b/api/core/tools/provider/builtin/google/tools/google_search.yaml @@ -0,0 +1,43 @@ +identity: + name: google_search + author: Dify + label: + en_US: GoogleSearch + zh_Hans: 谷歌搜索 +description: + human: + en_US: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query. + zh_Hans: 一个用于执行 Google SERP 搜索并提取片段和网页的工具。输入应该是一个搜索查询。 + llm: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query. +parameters: + - name: query + type: string + required: true + label: + en_US: Query string + zh_Hans: 查询语句 + human_description: + en_US: used for searching + zh_Hans: 用于搜索网页内容 + llm_description: key words for searching + form: llm + - name: result_type + type: select + required: true + options: + - value: text + label: + en_US: text + zh_Hans: 文本 + - value: link + label: + en_US: link + zh_Hans: 链接 + default: link + label: + en_US: Result type + zh_Hans: 结果类型 + human_description: + en_US: used for selecting the result type, text or link + zh_Hans: 用于选择结果类型,使用文本还是链接进行展示 + form: form diff --git a/api/core/tools/provider/builtin/stablediffusion/_assets/icon.png b/api/core/tools/provider/builtin/stablediffusion/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fc372b28f1ccfd7bea27dfe7ef0450e98a0be7e1 GIT binary patch literal 16324 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 literal 0 HcmV?d00001 diff --git a/api/core/tools/provider/builtin/stablediffusion/stablediffusion.py b/api/core/tools/provider/builtin/stablediffusion/stablediffusion.py new file mode 100644 index 000000000..ea18349ae --- /dev/null +++ b/api/core/tools/provider/builtin/stablediffusion/stablediffusion.py @@ -0,0 +1,26 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.stablediffusion.tools.stable_diffusion import StableDiffusionTool + +from typing import Any, Dict + +class StableDiffusionProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + StableDiffusionTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "prompt": "cat", + "lora": "", + "steps": 1, + "width": 512, + "height": 512, + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/stablediffusion/stablediffusion.yaml b/api/core/tools/provider/builtin/stablediffusion/stablediffusion.yaml new file mode 100644 index 000000000..8bb3a3c0d --- /dev/null +++ b/api/core/tools/provider/builtin/stablediffusion/stablediffusion.yaml @@ -0,0 +1,29 @@ +identity: + author: Dify + name: stablediffusion + label: + en_US: Stable Diffusion + zh_Hans: Stable Diffusion + description: + en_US: Stable Diffusion is a tool for generating images which can be deployed locally. + zh_Hans: Stable Diffusion 是一个可以在本地部署的图片生成的工具。 + icon: icon.png +credentails_for_provider: + base_url: + type: secret-input + required: true + label: + en_US: Base URL + zh_Hans: StableDiffusion服务器的Base URL + placeholder: + en_US: Please input your StableDiffusion server's Base URL + zh_Hans: 请输入你的 StableDiffusion 服务器的 Base URL + model: + type: text-input + required: true + label: + en_US: Model + zh_Hans: 模型 + placeholder: + en_US: Please input your model + zh_Hans: 请输入你的模型名称 diff --git a/api/core/tools/provider/builtin/stablediffusion/tools/stable_diffusion.py b/api/core/tools/provider/builtin/stablediffusion/tools/stable_diffusion.py new file mode 100644 index 000000000..02fc7448e --- /dev/null +++ b/api/core/tools/provider/builtin/stablediffusion/tools/stable_diffusion.py @@ -0,0 +1,244 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter, ToolParamterOption +from core.tools.entities.common_entities import I18nObject +from core.tools.errors import ToolProviderCredentialValidationError + +from typing import Any, Dict, List, Union +from httpx import post +from os.path import join +from base64 import b64decode, b64encode +from PIL import Image + +import json +import io + +from copy import deepcopy + +DRAW_TEXT_OPTIONS = { + "prompt": "", + "negative_prompt": "", + "seed": -1, + "subseed": -1, + "subseed_strength": 0, + "seed_resize_from_h": -1, + 'sampler_index': 'DPM++ SDE Karras', + "seed_resize_from_w": -1, + "batch_size": 1, + "n_iter": 1, + "steps": 10, + "cfg_scale": 7, + "width": 1024, + "height": 1024, + "restore_faces": False, + "do_not_save_samples": False, + "do_not_save_grid": False, + "eta": 0, + "denoising_strength": 0, + "s_min_uncond": 0, + "s_churn": 0, + "s_tmax": 0, + "s_tmin": 0, + "s_noise": 0, + "override_settings": {}, + "override_settings_restore_afterwards": True, + "refiner_switch_at": 0, + "disable_extra_networks": False, + "comments": {}, + "enable_hr": False, + "firstphase_width": 0, + "firstphase_height": 0, + "hr_scale": 2, + "hr_second_pass_steps": 0, + "hr_resize_x": 0, + "hr_resize_y": 0, + "hr_prompt": "", + "hr_negative_prompt": "", + "script_args": [], + "send_images": True, + "save_images": False, + "alwayson_scripts": {} +} + +class StableDiffusionTool(BuiltinTool): + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + # base url + base_url = self.runtime.credentials.get('base_url', None) + if not base_url: + return self.create_text_message('Please input base_url') + model = self.runtime.credentials.get('model', None) + if not model: + return self.create_text_message('Please input model') + + # set model + try: + url = join(base_url, 'sdapi/v1/options') + response = post(url, data=json.dumps({ + 'sd_model_checkpoint': model + })) + if response.status_code != 200: + raise ToolProviderCredentialValidationError('Failed to set model, please tell user to set model') + except Exception as e: + raise ToolProviderCredentialValidationError('Failed to set model, please tell user to set model') + + + # prompt + prompt = tool_paramters.get('prompt', '') + if not prompt: + return self.create_text_message('Please input prompt') + + # get negative prompt + negative_prompt = tool_paramters.get('negative_prompt', '') + + # get size + width = tool_paramters.get('width', 1024) + height = tool_paramters.get('height', 1024) + + # get steps + steps = tool_paramters.get('steps', 1) + + # get lora + lora = tool_paramters.get('lora', '') + + # get image id + image_id = tool_paramters.get('image_id', '') + if image_id.strip(): + image_variable = self.get_default_image_variable() + if image_variable: + image_binary = self.get_variable_file(image_variable.name) + if not image_binary: + return self.create_text_message('Image not found, please request user to generate image firstly.') + + # convert image to RGB + image = Image.open(io.BytesIO(image_binary)) + image = image.convert("RGB") + buffer = io.BytesIO() + image.save(buffer, format="PNG") + image_binary = buffer.getvalue() + image.close() + + return self.img2img(base_url=base_url, + lora=lora, + image_binary=image_binary, + prompt=prompt, + negative_prompt=negative_prompt, + width=width, + height=height, + steps=steps) + + return self.text2img(base_url=base_url, + lora=lora, + prompt=prompt, + negative_prompt=negative_prompt, + width=width, + height=height, + steps=steps) + + def img2img(self, base_url: str, lora: str, image_binary: bytes, + prompt: str, negative_prompt: str, + width: int, height: int, steps: int) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + generate image + """ + draw_options = { + "init_images": [b64encode(image_binary).decode('utf-8')], + "prompt": "", + "negative_prompt": negative_prompt, + "denoising_strength": 0.9, + "width": width, + "height": height, + "cfg_scale": 7, + "sampler_name": "Euler a", + "restore_faces": False, + "steps": steps, + "script_args": ["outpainting mk2"] + } + + if lora: + draw_options['prompt'] = f'{lora},{prompt}' + else: + draw_options['prompt'] = prompt + + try: + url = join(base_url, 'sdapi/v1/img2img') + response = post(url, data=json.dumps(draw_options), timeout=120) + if response.status_code != 200: + return self.create_text_message('Failed to generate image') + + image = response.json()['images'][0] + + return self.create_blob_message(blob=b64decode(image), + meta={ 'mime_type': 'image/png' }, + save_as=self.VARIABLE_KEY.IMAGE.value) + + except Exception as e: + return self.create_text_message('Failed to generate image') + + def text2img(self, base_url: str, lora: str, prompt: str, negative_prompt: str, width: int, height: int, steps: int) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + generate image + """ + # copy draw options + draw_options = deepcopy(DRAW_TEXT_OPTIONS) + + if lora: + draw_options['prompt'] = f'{lora},{prompt}' + + draw_options['width'] = width + draw_options['height'] = height + draw_options['steps'] = steps + draw_options['negative_prompt'] = negative_prompt + + try: + url = join(base_url, 'sdapi/v1/txt2img') + response = post(url, data=json.dumps(draw_options), timeout=120) + if response.status_code != 200: + return self.create_text_message('Failed to generate image') + + image = response.json()['images'][0] + + return self.create_blob_message(blob=b64decode(image), + meta={ 'mime_type': 'image/png' }, + save_as=self.VARIABLE_KEY.IMAGE.value) + + except Exception as e: + return self.create_text_message('Failed to generate image') + + + def get_runtime_parameters(self) -> List[ToolParamter]: + parameters = [ + ToolParamter(name='prompt', + label=I18nObject(en_US='Prompt', zh_Hans='Prompt'), + human_description=I18nObject( + en_US='Image prompt, you can check the official documentation of Stable Diffusion', + zh_Hans='图像提示词,您可以查看 Stable Diffusion 的官方文档', + ), + type=ToolParamter.ToolParameterType.STRING, + form=ToolParamter.ToolParameterForm.LLM, + llm_description='Image prompt of Stable Diffusion, you should describe the image you want to generate as a list of words as possible as detailed, the prompt must be written in English.', + required=True), + ] + if len(self.list_default_image_variables()) != 0: + parameters.append( + ToolParamter(name='image_id', + label=I18nObject(en_US='image_id', zh_Hans='image_id'), + human_description=I18nObject( + en_US='Image id of the image you want to generate based on, if you want to generate image based on the default image, you can leave this field empty.', + zh_Hans='您想要生成的图像的图像 ID,如果您想要基于默认图像生成图像,则可以将此字段留空。', + ), + type=ToolParamter.ToolParameterType.STRING, + form=ToolParamter.ToolParameterForm.LLM, + llm_description='Image id of the original image, you can leave this field empty if you want to generate a new image.', + required=True, + options=[ToolParamterOption( + value=i.name, + label=I18nObject(en_US=i.name, zh_Hans=i.name) + ) for i in self.list_default_image_variables()]) + ) + + return parameters diff --git a/api/core/tools/provider/builtin/stablediffusion/tools/stable_diffusion.yaml b/api/core/tools/provider/builtin/stablediffusion/tools/stable_diffusion.yaml new file mode 100644 index 000000000..cd20a81c1 --- /dev/null +++ b/api/core/tools/provider/builtin/stablediffusion/tools/stable_diffusion.yaml @@ -0,0 +1,77 @@ +identity: + name: stable_diffusion + author: Dify + label: + en_US: Stable Diffusion WebUI + zh_Hans: Stable Diffusion WebUI +description: + human: + en_US: A tool for generating images which can be deployed locally, you can use stable-diffusion-webui to deploy it. + zh_Hans: 一个可以在本地部署的图片生成的工具,您可以使用 stable-diffusion-webui 来部署它。 + llm: draw the image you want based on your prompt. +parameters: + - name: prompt + type: string + required: true + label: + en_US: Prompt + zh_Hans: 提示词 + human_description: + en_US: Image prompt, you can check the official documentation of Stable Diffusion + zh_Hans: 图像提示词,您可以查看 Stable Diffusion 的官方文档 + llm_description: Image prompt of Stable Diffusion, you should describe the image you want to generate as a list of words as possible as detailed, the prompt must be written in English. + form: llm + - name: lora + type: string + required: false + label: + en_US: Lora + zh_Hans: Lora + human_description: + en_US: Lora + zh_Hans: Lora + form: form + - name: steps + type: number + required: false + label: + en_US: Steps + zh_Hans: Steps + human_description: + en_US: Steps + zh_Hans: Steps + form: form + default: 10 + - name: width + type: number + required: false + label: + en_US: Width + zh_Hans: Width + human_description: + en_US: Width + zh_Hans: Width + form: form + default: 1024 + - name: height + type: number + required: false + label: + en_US: Height + zh_Hans: Height + human_description: + en_US: Height + zh_Hans: Height + form: form + default: 1024 + - name: negative_prompt + type: string + required: false + label: + en_US: Negative prompt + zh_Hans: Negative prompt + human_description: + en_US: Negative prompt + zh_Hans: Negative prompt + form: form + default: bad art, ugly, deformed, watermark, duplicated, discontinuous lines diff --git a/api/core/tools/provider/builtin/time/_assets/icon.svg b/api/core/tools/provider/builtin/time/_assets/icon.svg new file mode 100644 index 000000000..6d7118aed --- /dev/null +++ b/api/core/tools/provider/builtin/time/_assets/icon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/time/time.py b/api/core/tools/provider/builtin/time/time.py new file mode 100644 index 000000000..24fd287d1 --- /dev/null +++ b/api/core/tools/provider/builtin/time/time.py @@ -0,0 +1,16 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.time.tools.current_time import CurrentTimeTool + +from typing import Any, Dict + +class WikiPediaProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + CurrentTimeTool().invoke( + user_id='', + tool_paramters={}, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/time/time.yaml b/api/core/tools/provider/builtin/time/time.yaml new file mode 100644 index 000000000..5a2c3395f --- /dev/null +++ b/api/core/tools/provider/builtin/time/time.yaml @@ -0,0 +1,11 @@ +identity: + author: Dify + name: time + label: + en_US: CurrentTime + zh_Hans: 时间 + description: + en_US: A tool for getting the current time. + zh_Hans: 一个用于获取当前时间的工具。 + icon: icon.svg +credentails_for_provider: diff --git a/api/core/tools/provider/builtin/time/tools/current_time.py b/api/core/tools/provider/builtin/time/tools/current_time.py new file mode 100644 index 000000000..ce380cd5b --- /dev/null +++ b/api/core/tools/provider/builtin/time/tools/current_time.py @@ -0,0 +1,17 @@ +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + +from typing import Any, Dict, List, Union + +from datetime import datetime, timezone + +class CurrentTimeTool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + return self.create_text_message(f'{datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S %Z")}') + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/time/tools/current_time.yaml b/api/core/tools/provider/builtin/time/tools/current_time.yaml new file mode 100644 index 000000000..2d86e4db4 --- /dev/null +++ b/api/core/tools/provider/builtin/time/tools/current_time.yaml @@ -0,0 +1,12 @@ +identity: + name: current_time + author: Dify + label: + en_US: Current Time + zh_Hans: 获取当前时间 +description: + human: + en_US: A tool for getting the current time. + zh_Hans: 一个用于获取当前时间的工具。 + llm: A tool for getting the current time. +parameters: diff --git a/api/core/tools/provider/builtin/vectorizer/_assets/icon.png b/api/core/tools/provider/builtin/vectorizer/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..52f18db84372dcfc2968be27d75aec0fca430d55 GIT binary patch literal 1875 zcmV-Z2dwysP)@~0drDELIAGL9O(c600d`2O+f$vv5yP#K9NCX-bJ2W9kC`eGaijACx zhBFjc*ky2>?e6T%?##SRZhn%L(|PVTe*c;GF(11` z9*@W4X;*@*2Gy~!>z}`AGz{piAf%TRy zPyBEts3p9=o9el+Yx61knV_D>7>ErW`{=pWm=JS8n@1VE}u9xEi-HYR}2dhC&8+dbrA#S6fU7l0Wr05e_yX1oB*JVDGH=-zq# z;33h*CK;o%Lezhd=ultdI{WuF-oLj-RR4=;sZO-AMyxm&;IJ^p-~iFkz;5G5EDOW@ zDhxAoBfoKA`08t7_UmZlwT#+NL=)c;8?nhaF?AY}1&+N;bn;lT(UaH^qhWep80ZFR zfgbN*6;j=W-%_sAPfoE?2c#JU2AH1PDYlR@e)&ErgMw;hQT=+&w7Q<9 z+oBeEA>IxmBMz7>2xT~#iohRpX{zA@n*T8LM2rSiio}%G&&p!KvxZ`q3RVPIxxe!o zRqeZ1h0FOPxoz6}NfZt0{XILcQRt=7xtE+_#RXlTZx|MTBm|IwIhmq7c&OHHP`I4s zyV>nr3SeghtTlpcmhq#uI^Ubbs^WK?cvUUWcUcQO7SqwHqiAb-arV6*9I0s0jMSWi=zIA~Nw;+eH8_|DTomwnYrk@&9$h{y$6j)%)ZW z76DXyKQKK44rOdRF&%HRU=e`R|I4c4x?|&mQjY-BbMUgwU0}tr`vJ}c(DDCEhDQMA zg=Dyx`)S3w06PBPWI)8i&rpWzt6N(2lHptcRsV0g02_Kri zJ38-POdaE+_j9@*;7kBrpMG5N*l9CxaXM#{xqClwIs$YyIH~UC-)dWFoJ-a*ei?c{ zaJnr8#g$GbRNX$&GJh)`D5G1^U~1#|5&csw*hg9hoC*LV>ed3NVxv>=&2Fqnkj5D{ z&djG7r!MGb!GdRNS6g>6<717X48A|YsQ~D8t`0yaff4kHg=0oVaGr)v|41yjyeX3o z&IQ0N!dx$WM2E%8W_-X>h~c!MD`Vhrh3!55MPL!Yg*!m6$8Bk9md3kwu%8pgoe{BbKRV5#n_|MXAhkq_i^Ftfbv0>};-oxA1BAd2s@rF} zcebxI@8yq{DbXIAXt9xMnPDe`NlJIC0vI&v(e1!vakGv`87}}cUI1pi0L*v+nDGKI z6Mv8!(K>mokYwBVgWT{iVviM)Y@75b!x{3}A)u+&w_*Zx{7aMG4Ot+dJCzE>o+lg= zpmufZdADcCW0ru%lb$c1m<4S=`FWf?rWl{Socvt*K=!GTkHS$3>7w}QC66}SuKY~W zqs*Jy$f=HnU7MR!6(XF*^Kkv+Zsow}$aav-bnK(aB)8-7csw2t_#fh*6^8a$&I|wm N002ovPDHLkV1mtmh`ay* literal 0 HcmV?d00001 diff --git a/api/core/tools/provider/builtin/vectorizer/tools/test_data.py b/api/core/tools/provider/builtin/vectorizer/tools/test_data.py new file mode 100644 index 000000000..1506ac0c9 --- /dev/null +++ b/api/core/tools/provider/builtin/vectorizer/tools/test_data.py @@ -0,0 +1 @@ +VECTORIZER_ICON_PNG = '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' \ No newline at end of file diff --git a/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.py b/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.py new file mode 100644 index 000000000..d6d70b345 --- /dev/null +++ b/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.py @@ -0,0 +1,74 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter +from core.tools.provider.builtin.vectorizer.tools.test_data import VECTORIZER_ICON_PNG +from core.tools.errors import ToolProviderCredentialValidationError + +from typing import Any, Dict, List, Union +from httpx import post +from base64 import b64decode + +class VectorizerTool(BuiltinTool): + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + api_key_name = self.runtime.credentials.get('api_key_name', None) + api_key_value = self.runtime.credentials.get('api_key_value', None) + mode = tool_paramters.get('mode', 'test') + if mode == 'production': + mode = 'preview' + + if not api_key_name or not api_key_value: + raise ToolProviderCredentialValidationError('Please input api key name and value') + + image_id = tool_paramters.get('image_id', '') + if not image_id: + return self.create_text_message('Please input image id') + + if image_id.startswith('__test_'): + image_binary = b64decode(VECTORIZER_ICON_PNG) + else: + image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE) + if not image_binary: + return self.create_text_message('Image not found, please request user to generate image firstly.') + + response = post( + 'https://vectorizer.ai/api/v1/vectorize', + files={ + 'image': image_binary + }, + data={ + 'mode': mode + } if mode == 'test' else {}, + auth=(api_key_name, api_key_value), + timeout=30 + ) + + if response.status_code != 200: + raise Exception(response.text) + + return [ + self.create_text_message('the vectorized svg is saved as an image.'), + self.create_blob_message(blob=response.content, + meta={'mime_type': 'image/svg+xml'}) + ] + + def get_runtime_parameters(self) -> List[ToolParamter]: + """ + override the runtime parameters + """ + return [ + ToolParamter.get_simple_instance( + name='image_id', + llm_description=f'the image id that you want to vectorize, \ + and the image id should be specified in \ + {[i.name for i in self.list_default_image_variables()]}', + type=ToolParamter.ToolParameterType.SELECT, + required=True, + options=[i.name for i in self.list_default_image_variables()] + ) + ] + + def is_tool_avaliable(self) -> bool: + return len(self.list_default_image_variables()) > 0 \ No newline at end of file diff --git a/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.yaml b/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.yaml new file mode 100644 index 000000000..2df4e3bf2 --- /dev/null +++ b/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.yaml @@ -0,0 +1,32 @@ +identity: + name: vectorizer + author: Dify + label: + en_US: Vectorizer.AI + zh_Hans: Vectorizer.AI +description: + human: + en_US: Convert your PNG and JPG images to SVG vectors quickly and easily. Fully automatically. Using AI. + zh_Hans: 一个将 PNG 和 JPG 图像快速轻松地转换为 SVG 矢量图的工具。 + llm: A tool for converting images to SVG vectors. you should input the image id as the input of this tool. the image id can be got from parameters. +parameters: + - name: mode + type: select + required: true + options: + - value: production + label: + en_US: production + zh_Hans: 生产模式 + - value: test + label: + en_US: test + zh_Hans: 测试模式 + default: test + label: + en_US: Mode + zh_Hans: 模式 + human_description: + en_US: It is free to integrate with and test out the API in test mode, no subscription required. + zh_Hans: 在测试模式下,可以免费测试API。 + form: form diff --git a/api/core/tools/provider/builtin/vectorizer/vectorizer.py b/api/core/tools/provider/builtin/vectorizer/vectorizer.py new file mode 100644 index 000000000..6abf11fbe --- /dev/null +++ b/api/core/tools/provider/builtin/vectorizer/vectorizer.py @@ -0,0 +1,23 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.vectorizer.tools.vectorizer import VectorizerTool + +from typing import Any, Dict + +class VectorizerProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + VectorizerTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "mode": "test", + "image_id": "__test_123" + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/vectorizer/vectorizer.yaml b/api/core/tools/provider/builtin/vectorizer/vectorizer.yaml new file mode 100644 index 000000000..566335e0c --- /dev/null +++ b/api/core/tools/provider/builtin/vectorizer/vectorizer.yaml @@ -0,0 +1,36 @@ +identity: + author: Dify + name: vectorizer + label: + en_US: Vectorizer.AI + zh_Hans: Vectorizer.AI + description: + en_US: Convert your PNG and JPG images to SVG vectors quickly and easily. Fully automatically. Using AI. + zh_Hans: 一个将 PNG 和 JPG 图像快速轻松地转换为 SVG 矢量图的工具。 + icon: icon.png +credentails_for_provider: + api_key_name: + type: secret-input + required: true + label: + en_US: Vectorizer.AI API Key name + zh_Hans: Vectorizer.AI API Key name + placeholder: + en_US: Please input your Vectorizer.AI ApiKey name + zh_Hans: 请输入你的 Vectorizer.AI ApiKey name + help: + en_US: Get your Vectorizer.AI API Key from Vectorizer.AI. + zh_Hans: 从 Vectorizer.AI 获取您的 Vectorizer.AI API Key。 + url: https://vectorizer.ai/api + api_key_value: + type: secret-input + required: true + label: + en_US: Vectorizer.AI API Key + zh_Hans: Vectorizer.AI API Key + placeholder: + en_US: Please input your Vectorizer.AI ApiKey + zh_Hans: 请输入你的 Vectorizer.AI ApiKey + help: + en_US: Get your Vectorizer.AI API Key from Vectorizer.AI. + zh_Hans: 从 Vectorizer.AI 获取您的 Vectorizer.AI API Key。 diff --git a/api/core/tools/provider/builtin/webscraper/_assets/icon.svg b/api/core/tools/provider/builtin/webscraper/_assets/icon.svg new file mode 100644 index 000000000..8123199a3 --- /dev/null +++ b/api/core/tools/provider/builtin/webscraper/_assets/icon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/webscraper/tools/webscraper.py b/api/core/tools/provider/builtin/webscraper/tools/webscraper.py new file mode 100644 index 000000000..d646720a3 --- /dev/null +++ b/api/core/tools/provider/builtin/webscraper/tools/webscraper.py @@ -0,0 +1,28 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.errors import ToolInvokeError + +from typing import Any, Dict, List, Union + +class WebscraperTool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + try: + url = tool_paramters.get('url', '') + user_agent = tool_paramters.get('user_agent', '') + if not url: + return self.create_text_message('Please input url') + + # get webpage + result = self.get_url(url, user_agent=user_agent) + + # summarize and return + return self.create_text_message(self.summary(user_id=user_id, content=result)) + except Exception as e: + raise ToolInvokeError(str(e)) + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/webscraper/tools/webscraper.yaml b/api/core/tools/provider/builtin/webscraper/tools/webscraper.yaml new file mode 100644 index 000000000..93cf7a044 --- /dev/null +++ b/api/core/tools/provider/builtin/webscraper/tools/webscraper.yaml @@ -0,0 +1,34 @@ +identity: + name: webscraper + author: Dify + label: + en_US: Web Scraper + zh_Hans: 网页爬虫 +description: + human: + en_US: A tool for scraping webpages. + zh_Hans: 一个用于爬取网页的工具。 + llm: A tool for scraping webpages. Input should be a URL. +parameters: + - name: url + type: string + required: true + label: + en_US: URL + zh_Hans: 网页链接 + human_description: + en_US: used for linking to webpages + zh_Hans: 用于链接到网页 + llm_description: url for scraping + form: llm + - name: user_agent + type: string + required: false + label: + en_US: User Agent + zh_Hans: User Agent + human_description: + en_US: used for identifying the browser. + zh_Hans: 用于识别浏览器。 + form: form + default: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.1000.0 Safari/537.36 diff --git a/api/core/tools/provider/builtin/webscraper/webscraper.py b/api/core/tools/provider/builtin/webscraper/webscraper.py new file mode 100644 index 000000000..9cfb7ecac --- /dev/null +++ b/api/core/tools/provider/builtin/webscraper/webscraper.py @@ -0,0 +1,23 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.webscraper.tools.webscraper import WebscraperTool + +from typing import Any, Dict, List + +class WebscraperProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + WebscraperTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + 'url': 'https://www.google.com', + 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/webscraper/webscraper.yaml b/api/core/tools/provider/builtin/webscraper/webscraper.yaml new file mode 100644 index 000000000..a1a99f99e --- /dev/null +++ b/api/core/tools/provider/builtin/webscraper/webscraper.yaml @@ -0,0 +1,11 @@ +identity: + author: Dify + name: webscraper + label: + en_US: WebScraper + zh_Hans: 网页抓取 + description: + en_US: Web Scrapper tool kit is used to scrape web + zh_Hans: 一个用于抓取网页的工具。 + icon: icon.svg +credentails_for_provider: diff --git a/api/core/tools/provider/builtin/wikipedia/_assets/icon.svg b/api/core/tools/provider/builtin/wikipedia/_assets/icon.svg new file mode 100644 index 000000000..fe652aacf --- /dev/null +++ b/api/core/tools/provider/builtin/wikipedia/_assets/icon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/wikipedia/tools/wikipedia_search.py b/api/core/tools/provider/builtin/wikipedia/tools/wikipedia_search.py new file mode 100644 index 000000000..c2764455c --- /dev/null +++ b/api/core/tools/provider/builtin/wikipedia/tools/wikipedia_search.py @@ -0,0 +1,37 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage + +from pydantic import BaseModel, Field + +from typing import Any, Dict, List, Union + +from langchain import WikipediaAPIWrapper +from langchain.tools import WikipediaQueryRun + +class WikipediaInput(BaseModel): + query: str = Field(..., description="search query.") + +class WikiPediaSearchTool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + query = tool_paramters.get('query', '') + if not query: + return self.create_text_message('Please input query') + + tool = WikipediaQueryRun( + name="wikipedia", + api_wrapper=WikipediaAPIWrapper(doc_content_chars_max=4000), + args_schema=WikipediaInput + ) + + result = tool.run(tool_input={ + 'query': query + }) + + return self.create_text_message(self.summary(user_id=user_id,content=result)) + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/wikipedia/tools/wikipedia_search.yaml b/api/core/tools/provider/builtin/wikipedia/tools/wikipedia_search.yaml new file mode 100644 index 000000000..3bbc65d80 --- /dev/null +++ b/api/core/tools/provider/builtin/wikipedia/tools/wikipedia_search.yaml @@ -0,0 +1,24 @@ +identity: + name: wikipedia_search + author: Dify + label: + en_US: WikipediaSearch + zh_Hans: 维基百科搜索 + icon: icon.svg +description: + human: + en_US: A tool for performing a Wikipedia search and extracting snippets and webpages. + zh_Hans: 一个用于执行维基百科搜索并提取片段和网页的工具。 + llm: A tool for performing a Wikipedia search and extracting snippets and webpages. Input should be a search query. +parameters: + - name: query + type: string + required: true + label: + en_US: Query string + zh_Hans: 查询语句 + human_description: + en_US: key words for searching + zh_Hans: 查询关键词 + llm_description: key words for searching + form: llm diff --git a/api/core/tools/provider/builtin/wikipedia/wikipedia.py b/api/core/tools/provider/builtin/wikipedia/wikipedia.py new file mode 100644 index 000000000..11af4de73 --- /dev/null +++ b/api/core/tools/provider/builtin/wikipedia/wikipedia.py @@ -0,0 +1,20 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.wikipedia.tools.wikipedia_search import WikiPediaSearchTool + +class WikiPediaProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: dict) -> None: + try: + WikiPediaSearchTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "query": "misaka mikoto", + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/wikipedia/wikipedia.yaml b/api/core/tools/provider/builtin/wikipedia/wikipedia.yaml new file mode 100644 index 000000000..801d7d174 --- /dev/null +++ b/api/core/tools/provider/builtin/wikipedia/wikipedia.yaml @@ -0,0 +1,11 @@ +identity: + author: Dify + name: wikipedia + label: + en_US: Wikipedia + zh_Hans: 维基百科 + description: + en_US: Wikipedia is a free online encyclopedia, created and edited by volunteers around the world. + zh_Hans: 维基百科是一个由全世界的志愿者创建和编辑的免费在线百科全书。 + icon: icon.svg +credentails_for_provider: diff --git a/api/core/tools/provider/builtin/wolframalpha/_assets/icon.svg b/api/core/tools/provider/builtin/wolframalpha/_assets/icon.svg new file mode 100644 index 000000000..2caf32ee6 --- /dev/null +++ b/api/core/tools/provider/builtin/wolframalpha/_assets/icon.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/wolframalpha/tools/wolframalpha.py b/api/core/tools/provider/builtin/wolframalpha/tools/wolframalpha.py new file mode 100644 index 000000000..787bca32c --- /dev/null +++ b/api/core/tools/provider/builtin/wolframalpha/tools/wolframalpha.py @@ -0,0 +1,77 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.errors import ToolProviderCredentialValidationError, ToolInvokeError + +from typing import Any, Dict, List, Union + +from httpx import get + +class WolframAlphaTool(BuiltinTool): + _base_url = 'https://api.wolframalpha.com/v2/query' + + def _invoke(self, + user_id: str, + tool_paramters: Dict[str, Any], + ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + query = tool_paramters.get('query', '') + if not query: + return self.create_text_message('Please input query') + appid = self.runtime.credentials.get('appid', '') + if not appid: + raise ToolProviderCredentialValidationError('Please input appid') + + params = { + 'appid': appid, + 'input': query, + 'includepodid': 'Result', + 'format': 'plaintext', + 'output': 'json' + } + + finished = False + result = None + # try 3 times at most + counter = 0 + + while not finished and counter < 3: + counter += 1 + try: + response = get(self._base_url, params=params, timeout=20) + response.raise_for_status() + response_data = response.json() + except Exception as e: + raise ToolInvokeError(str(e)) + + if 'success' not in response_data['queryresult'] or response_data['queryresult']['success'] != True: + query_result = response_data.get('queryresult', {}) + if 'error' in query_result and query_result['error']: + if 'msg' in query_result['error']: + if query_result['error']['msg'] == 'Invalid appid': + raise ToolProviderCredentialValidationError('Invalid appid') + raise ToolInvokeError('Failed to invoke tool') + + if 'didyoumeans' in response_data['queryresult']: + # get the most likely interpretation + query = '' + max_score = 0 + for didyoumean in response_data['queryresult']['didyoumeans']: + if float(didyoumean['score']) > max_score: + query = didyoumean['val'] + max_score = float(didyoumean['score']) + + params['input'] = query + else: + finished = True + if 'souces' in response_data['queryresult']: + return self.create_link_message(response_data['queryresult']['sources']['url']) + elif 'pods' in response_data['queryresult']: + result = response_data['queryresult']['pods'][0]['subpods'][0]['plaintext'] + + if not finished or not result: + return self.create_text_message('No result found') + + return self.create_text_message(result) + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/wolframalpha/tools/wolframalpha.yaml b/api/core/tools/provider/builtin/wolframalpha/tools/wolframalpha.yaml new file mode 100644 index 000000000..0e7e8fad9 --- /dev/null +++ b/api/core/tools/provider/builtin/wolframalpha/tools/wolframalpha.yaml @@ -0,0 +1,23 @@ +identity: + name: wolframalpha + author: Dify + label: + en_US: WolframAlpha + zh_Hans: WolframAlpha +description: + human: + en_US: WolframAlpha is a powerful computational knowledge engine. + zh_Hans: WolframAlpha 是一个强大的计算知识引擎。 + llm: WolframAlpha is a powerful computational knowledge engine. one single query can get the answer of a question. +parameters: + - name: query + type: string + required: true + label: + en_US: Query string + zh_Hans: 计算语句 + human_description: + en_US: used for calculating + zh_Hans: 用于计算最终结果 + llm_description: a single query for calculating + form: llm diff --git a/api/core/tools/provider/builtin/wolframalpha/wolframalpha.py b/api/core/tools/provider/builtin/wolframalpha/wolframalpha.py new file mode 100644 index 000000000..56e367257 --- /dev/null +++ b/api/core/tools/provider/builtin/wolframalpha/wolframalpha.py @@ -0,0 +1,24 @@ +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolProviderType +from core.tools.tool.tool import Tool +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.wolframalpha.tools.wolframalpha import WolframAlphaTool + +from typing import Any, Dict, List + +class GoogleProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + try: + WolframAlphaTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "query": "1+2+....+111", + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/wolframalpha/wolframalpha.yaml b/api/core/tools/provider/builtin/wolframalpha/wolframalpha.yaml new file mode 100644 index 000000000..1d2a03810 --- /dev/null +++ b/api/core/tools/provider/builtin/wolframalpha/wolframalpha.yaml @@ -0,0 +1,24 @@ +identity: + author: Dify + name: wolframalpha + label: + en_US: WolframAlpha + zh_Hans: WolframAlpha + description: + en_US: WolframAlpha is a powerful computational knowledge engine. + zh_Hans: WolframAlpha 是一个强大的计算知识引擎。 + icon: icon.svg +credentails_for_provider: + appid: + type: secret-input + required: true + label: + en_US: WolframAlpha AppID + zh_Hans: WolframAlpha AppID + placeholder: + en_US: Please input your WolframAlpha AppID + zh_Hans: 请输入你的 WolframAlpha AppID + help: + en_US: Get your WolframAlpha AppID from WolframAlpha, please use "full results" api access. + zh_Hans: 从 WolframAlpha 获取您的 WolframAlpha AppID,请使用 "full results" API。 + url: https://products.wolframalpha.com/api diff --git a/api/core/tools/provider/builtin/yahoo/_assets/icon.png b/api/core/tools/provider/builtin/yahoo/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..35d756f75410dbdf74ca14c8fba6e660e20b27d8 GIT binary patch literal 7647 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 Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + symbol = tool_paramters.get('symbol', '') + if not symbol: + return self.create_text_message('Please input symbol') + + time_range = [None, None] + start_date = tool_paramters.get('start_date', '') + if start_date: + time_range[0] = start_date + else: + time_range[0] = '1800-01-01' + + end_date = tool_paramters.get('end_date', '') + if end_date: + time_range[1] = end_date + else: + time_range[1] = datetime.now().strftime('%Y-%m-%d') + + stock_data = download(symbol, start=time_range[0], end=time_range[1]) + max_segments = min(15, len(stock_data)) + rows_per_segment = len(stock_data) // max_segments + summary_data = [] + for i in range(max_segments): + start_idx = i * rows_per_segment + end_idx = (i + 1) * rows_per_segment if i < max_segments - 1 else len(stock_data) + segment_data = stock_data.iloc[start_idx:end_idx] + segment_summary = { + 'Start Date': segment_data.index[0], + 'End Date': segment_data.index[-1], + 'Average Close': segment_data['Close'].mean(), + 'Average Volume': segment_data['Volume'].mean(), + 'Average Open': segment_data['Open'].mean(), + 'Average High': segment_data['High'].mean(), + 'Average Low': segment_data['Low'].mean(), + 'Average Adj Close': segment_data['Adj Close'].mean(), + 'Max Close': segment_data['Close'].max(), + 'Min Close': segment_data['Close'].min(), + 'Max Volume': segment_data['Volume'].max(), + 'Min Volume': segment_data['Volume'].min(), + 'Max Open': segment_data['Open'].max(), + 'Min Open': segment_data['Open'].min(), + 'Max High': segment_data['High'].max(), + 'Min High': segment_data['High'].min(), + } + + summary_data.append(segment_summary) + + summary_df = pd.DataFrame(summary_data) + + try: + return self.create_text_message(str(summary_df.to_dict())) + except (HTTPError, ReadTimeout): + return self.create_text_message(f'There is a internet connection problem. Please try again later.') + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/yahoo/tools/analytics.yaml b/api/core/tools/provider/builtin/yahoo/tools/analytics.yaml new file mode 100644 index 000000000..0daee2acf --- /dev/null +++ b/api/core/tools/provider/builtin/yahoo/tools/analytics.yaml @@ -0,0 +1,46 @@ +identity: + name: yahoo_finance_analytics + author: Dify + label: + en_US: Analytics + zh_Hans: 分析 + icon: icon.svg +description: + human: + en_US: A tool for get analytics about a ticker from Yahoo Finance. + zh_Hans: 一个用于从雅虎财经获取分析数据的工具。 + llm: A tool for get analytics from Yahoo Finance. Input should be the ticker symbol like AAPL. +parameters: + - name: symbol + type: string + required: true + label: + en_US: Ticker symbol + zh_Hans: 股票代码 + human_description: + en_US: The ticker symbol of the company you want to analyze. + zh_Hans: 你想要搜索的公司的股票代码。 + llm_description: The ticker symbol of the company you want to analyze. + form: llm + - name: start_date + type: string + required: false + label: + en_US: Start date + zh_Hans: 开始日期 + human_description: + en_US: The start date of the analytics. + zh_Hans: 分析的开始日期。 + llm_description: The start date of the analytics, the format of the date must be YYYY-MM-DD like 2020-01-01. + form: llm + - name: end_date + type: string + required: false + label: + en_US: End date + zh_Hans: 结束日期 + human_description: + en_US: The end date of the analytics. + zh_Hans: 分析的结束日期。 + llm_description: The end date of the analytics, the format of the date must be YYYY-MM-DD like 2024-01-01. + form: llm diff --git a/api/core/tools/provider/builtin/yahoo/tools/news.py b/api/core/tools/provider/builtin/yahoo/tools/news.py new file mode 100644 index 000000000..1fd118860 --- /dev/null +++ b/api/core/tools/provider/builtin/yahoo/tools/news.py @@ -0,0 +1,46 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage + +from typing import Any, Dict, List, Union +from requests.exceptions import HTTPError, ReadTimeout + +import yfinance + +class YahooFinanceSearchTickerTool(BuiltinTool): + def _invoke(self,user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + ''' + invoke tools + ''' + + query = tool_paramters.get('symbol', '') + if not query: + return self.create_text_message('Please input symbol') + + try: + return self.run(ticker=query, user_id=user_id) + except (HTTPError, ReadTimeout): + return self.create_text_message(f'There is a internet connection problem. Please try again later.') + + def run(self, ticker: str, user_id: str) -> ToolInvokeMessage: + company = yfinance.Ticker(ticker) + try: + if company.isin is None: + return self.create_text_message(f'Company ticker {ticker} not found.') + except (HTTPError, ReadTimeout, ConnectionError): + return self.create_text_message(f'Company ticker {ticker} not found.') + + links = [] + try: + links = [n['link'] for n in company.news if n['type'] == 'STORY'] + except (HTTPError, ReadTimeout, ConnectionError): + if not links: + return self.create_text_message(f'There is nothing about {ticker} ticker') + if not links: + return self.create_text_message(f'No news found for company that searched with {ticker} ticker.') + + result = '\n\n'.join([ + self.get_url(link) for link in links + ]) + + return self.create_text_message(self.summary(user_id=user_id, content=result)) diff --git a/api/core/tools/provider/builtin/yahoo/tools/news.yaml b/api/core/tools/provider/builtin/yahoo/tools/news.yaml new file mode 100644 index 000000000..db33c9622 --- /dev/null +++ b/api/core/tools/provider/builtin/yahoo/tools/news.yaml @@ -0,0 +1,24 @@ +identity: + name: yahoo_finance_news + author: Dify + label: + en_US: News + zh_Hans: 新闻 + icon: icon.svg +description: + human: + en_US: A tool for get news about a ticker from Yahoo Finance. + zh_Hans: 一个用于从雅虎财经获取新闻的工具。 + llm: A tool for get news from Yahoo Finance. Input should be the ticker symbol like AAPL. +parameters: + - name: symbol + type: string + required: true + label: + en_US: Ticker symbol + zh_Hans: 股票代码 + human_description: + en_US: The ticker symbol of the company you want to search. + zh_Hans: 你想要搜索的公司的股票代码。 + llm_description: The ticker symbol of the company you want to search. + form: llm diff --git a/api/core/tools/provider/builtin/yahoo/tools/ticker.py b/api/core/tools/provider/builtin/yahoo/tools/ticker.py new file mode 100644 index 000000000..029cc7b44 --- /dev/null +++ b/api/core/tools/provider/builtin/yahoo/tools/ticker.py @@ -0,0 +1,25 @@ +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.entities.tool_entities import ToolInvokeMessage + +from typing import Any, Dict, List, Union +from requests.exceptions import HTTPError, ReadTimeout + +from yfinance import Ticker + +class YahooFinanceSearchTickerTool(BuiltinTool): + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \ + -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + query = tool_paramters.get('symbol', '') + if not query: + return self.create_text_message('Please input symbol') + + try: + return self.create_text_message(self.run(ticker=query)) + except (HTTPError, ReadTimeout): + return self.create_text_message(f'There is a internet connection problem. Please try again later.') + + def run(self, ticker: str) -> str: + return str(Ticker(ticker).info) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/yahoo/tools/ticker.yaml b/api/core/tools/provider/builtin/yahoo/tools/ticker.yaml new file mode 100644 index 000000000..b90cfa632 --- /dev/null +++ b/api/core/tools/provider/builtin/yahoo/tools/ticker.yaml @@ -0,0 +1,24 @@ +identity: + name: yahoo_finance_ticker + author: Dify + label: + en_US: Ticker + zh_Hans: 股票信息 + icon: icon.svg +description: + human: + en_US: A tool for search ticker information from Yahoo Finance. + zh_Hans: 一个用于从雅虎财经搜索股票信息的工具。 + llm: A tool for search ticker information from Yahoo Finance. Input should be the ticker symbol like AAPL. +parameters: + - name: symbol + type: string + required: true + label: + en_US: Ticker symbol + zh_Hans: 股票代码 + human_description: + en_US: The ticker symbol of the company you want to search. + zh_Hans: 你想要搜索的公司的股票代码。 + llm_description: The ticker symbol of the company you want to search. + form: llm diff --git a/api/core/tools/provider/builtin/yahoo/yahoo.py b/api/core/tools/provider/builtin/yahoo/yahoo.py new file mode 100644 index 000000000..258ee3a6c --- /dev/null +++ b/api/core/tools/provider/builtin/yahoo/yahoo.py @@ -0,0 +1,20 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.yahoo.tools.ticker import YahooFinanceSearchTickerTool + +class YahooFinanceProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: dict) -> None: + try: + YahooFinanceSearchTickerTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "ticker": "MSFT", + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/yahoo/yahoo.yaml b/api/core/tools/provider/builtin/yahoo/yahoo.yaml new file mode 100644 index 000000000..d1802321f --- /dev/null +++ b/api/core/tools/provider/builtin/yahoo/yahoo.yaml @@ -0,0 +1,11 @@ +identity: + author: Dify + name: yahoo + label: + en_US: YahooFinance + zh_Hans: 雅虎财经 + description: + en_US: Finance, and Yahoo! get the latest news, stock quotes, and interactive chart with Yahoo! + zh_Hans: 雅虎财经,获取并整理出最新的新闻、股票报价等一切你想要的财经信息。 + icon: icon.png +credentails_for_provider: diff --git a/api/core/tools/provider/builtin/youtube/_assets/icon.png b/api/core/tools/provider/builtin/youtube/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3ab7908a5d0e9ac2fe670a1e15f8d2fd80c2128e GIT binary patch literal 1073 zcmV-11kU@3P)@~0drDELIAGL9O(c600d`2O+f$vv5yPkWkSfd>C&xD-(o@;={7Np;Q2q;(ye|?-3NL5<+1B zX1v$M|AOLIGYR3b4q@opPEi3}{1X(vI?-o#rglZ!IeUN^da^9}O0Y3~cC_mnikv+_ z7r!t;a7**_*wyX~KwlIc5Nt(X&>gwjtpS)XUyS`;^ro`}>sSLwDaHA|Cuy4YY;D#6 zIAdJtdcvLDT1&@wK#l->$)f53x2zT34!w~U|clX`y{d=Ppxxo>L=;yWPpAedB`L(sCO^oT|F z(@?JOJWzN+*iUGJJ`HU`k7&eoK*&MZuLC5!E8!XkvB{NixX=C6FomewA_JW$u^=zo~?LH`PaS4QFuGvro@E^FI z4MhN+xN7NoG!X%KqC`~>fJh+#U!tsf01{yc@%jLlOdXYrr!r Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + """ + invoke tools + """ + channel = tool_paramters.get('channel', '') + if not channel: + return self.create_text_message('Please input symbol') + + time_range = [None, None] + start_date = tool_paramters.get('start_date', '') + if start_date: + time_range[0] = start_date + else: + time_range[0] = '1800-01-01' + + end_date = tool_paramters.get('end_date', '') + if end_date: + time_range[1] = end_date + else: + time_range[1] = datetime.now().strftime('%Y-%m-%d') + + if 'google_api_key' not in self.runtime.credentials or not self.runtime.credentials['google_api_key']: + return self.create_text_message('Please input api key') + + youtube = build('youtube', 'v3', developerKey=self.runtime.credentials['google_api_key']) + + # try to get channel id + search_results = youtube.search().list(q='mrbeast', type='channel', order='relevance', part='id').execute() + channel_id = search_results['items'][0]['id']['channelId'] + + start_date, end_date = time_range + + start_date = datetime.strptime(start_date, '%Y-%m-%d').strftime('%Y-%m-%dT%H:%M:%SZ') + end_date = datetime.strptime(end_date, '%Y-%m-%d').strftime('%Y-%m-%dT%H:%M:%SZ') + + # get videos + time_range_videos = youtube.search().list( + part='snippet', channelId=channel_id, order='date', type='video', + publishedAfter=start_date, + publishedBefore=end_date + ).execute() + + def extract_video_data(video_list): + data = [] + for video in video_list['items']: + video_id = video['id']['videoId'] + video_info = youtube.videos().list(part='snippet,statistics', id=video_id).execute() + title = video_info['items'][0]['snippet']['title'] + views = video_info['items'][0]['statistics']['viewCount'] + data.append({'Title': title, 'Views': views}) + return data + + summary = extract_video_data(time_range_videos) + + return self.create_text_message(str(summary)) + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/youtube/tools/videos.yaml b/api/core/tools/provider/builtin/youtube/tools/videos.yaml new file mode 100644 index 000000000..3ac28d5d7 --- /dev/null +++ b/api/core/tools/provider/builtin/youtube/tools/videos.yaml @@ -0,0 +1,46 @@ +identity: + name: youtube_video_statistics + author: Dify + label: + en_US: Video statistics + zh_Hans: 视频统计 + icon: icon.svg +description: + human: + en_US: A tool for get statistics about a channel's videos. + zh_Hans: 一个用于获取油管频道视频统计数据的工具。 + llm: A tool for get statistics about a channel's videos. Input should be the name of the channel like PewDiePie. +parameters: + - name: channel + type: string + required: true + label: + en_US: Channel name + zh_Hans: 频道名 + human_description: + en_US: The name of the channel you want to search. + zh_Hans: 你想要搜索的油管频道名。 + llm_description: The name of the channel you want to search. + form: llm + - name: start_date + type: string + required: false + label: + en_US: Start date + zh_Hans: 开始日期 + human_description: + en_US: The start date of the analytics. + zh_Hans: 分析的开始日期。 + llm_description: The start date of the analytics, the format of the date must be YYYY-MM-DD like 2020-01-01. + form: llm + - name: end_date + type: string + required: false + label: + en_US: End date + zh_Hans: 结束日期 + human_description: + en_US: The end date of the analytics. + zh_Hans: 分析的结束日期。 + llm_description: The end date of the analytics, the format of the date must be YYYY-MM-DD like 2024-01-01. + form: llm diff --git a/api/core/tools/provider/builtin/youtube/youtube.py b/api/core/tools/provider/builtin/youtube/youtube.py new file mode 100644 index 000000000..047cfbe0e --- /dev/null +++ b/api/core/tools/provider/builtin/youtube/youtube.py @@ -0,0 +1,22 @@ +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.errors import ToolProviderCredentialValidationError + +from core.tools.provider.builtin.youtube.tools.videos import YoutubeVideosAnalyticsTool + +class YahooFinanceProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: dict) -> None: + try: + YoutubeVideosAnalyticsTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_paramters={ + "channel": "TOKYO GIRLS COLLECTION", + "start_date": "2020-01-01", + "end_date": "2024-12-31", + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/youtube/youtube.yaml b/api/core/tools/provider/builtin/youtube/youtube.yaml new file mode 100644 index 000000000..e5d3879d5 --- /dev/null +++ b/api/core/tools/provider/builtin/youtube/youtube.yaml @@ -0,0 +1,24 @@ +identity: + author: Dify + name: youtube + label: + en_US: Youtube + zh_Hans: Youtube + description: + en_US: Youtube + zh_Hans: Youtube(油管)是全球最大的视频分享网站,用户可以在上面上传、观看和分享视频。 + icon: icon.png +credentails_for_provider: + google_api_key: + type: secret-input + required: true + label: + en_US: Google API key + zh_Hans: Google API key + placeholder: + en_US: Please input your Google API key + zh_Hans: 请输入你的 Google API key + help: + en_US: Get your Google API key from Google + zh_Hans: 从 Google 获取您的 Google API key + url: https://console.developers.google.com/apis/credentials diff --git a/api/core/tools/provider/builtin_tool_provider.py b/api/core/tools/provider/builtin_tool_provider.py new file mode 100644 index 000000000..e071dcbea --- /dev/null +++ b/api/core/tools/provider/builtin_tool_provider.py @@ -0,0 +1,286 @@ +from abc import abstractmethod +from typing import List, Dict, Any + +from os import path, listdir +from yaml import load, FullLoader + +from core.tools.entities.tool_entities import ToolProviderType, \ + ToolParamter, ToolProviderCredentials +from core.tools.tool.tool import Tool +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.provider.tool_provider import ToolProviderController +from core.tools.entities.user_entities import UserToolProviderCredentials +from core.tools.errors import ToolNotFoundError, ToolProviderNotFoundError, \ + ToolParamterValidationError, ToolProviderCredentialValidationError + +import importlib + +class BuiltinToolProviderController(ToolProviderController): + def __init__(self, **data: Any) -> None: + if self.app_type == ToolProviderType.API_BASED or self.app_type == ToolProviderType.APP_BASED: + super().__init__(**data) + return + + # load provider yaml + provider = self.__class__.__module__.split('.')[-1] + yaml_path = path.join(path.dirname(path.realpath(__file__)), 'builtin', provider, f'{provider}.yaml') + try: + with open(yaml_path, 'r') as f: + provider_yaml = load(f.read(), FullLoader) + except: + raise ToolProviderNotFoundError(f'can not load provider yaml for {provider}') + + if 'credentails_for_provider' in provider_yaml and provider_yaml['credentails_for_provider'] is not None: + # set credentials name + for credential_name in provider_yaml['credentails_for_provider']: + provider_yaml['credentails_for_provider'][credential_name]['name'] = credential_name + + super().__init__(**{ + 'identity': provider_yaml['identity'], + 'credentials_schema': provider_yaml['credentails_for_provider'] if 'credentails_for_provider' in provider_yaml else None, + }) + + def _get_bulitin_tools(self) -> List[Tool]: + """ + returns a list of tools that the provider can provide + + :return: list of tools + """ + if self.tools: + return self.tools + + provider = self.identity.name + tool_path = path.join(path.dirname(path.realpath(__file__)), "builtin", provider, "tools") + # get all the yaml files in the tool path + tool_files = list(filter(lambda x: x.endswith(".yaml") and not x.startswith("__"), listdir(tool_path))) + tools = [] + for tool_file in tool_files: + with open(path.join(tool_path, tool_file), "r") as f: + # get tool name + tool_name = tool_file.split(".")[0] + tool = load(f.read(), FullLoader) + # get tool class, import the module + py_path = path.join(path.dirname(path.realpath(__file__)), 'builtin', provider, 'tools', f'{tool_name}.py') + spec = importlib.util.spec_from_file_location(f'core.tools.provider.builtin.{provider}.tools.{tool_name}', py_path) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + + # get all the classes in the module + classes = [x for _, x in vars(mod).items() + if isinstance(x, type) and x not in [BuiltinTool, Tool] and issubclass(x, BuiltinTool) + ] + assistant_tool_class = classes[0] + tools.append(assistant_tool_class(**tool)) + + self.tools = tools + return tools + + def get_credentails_schema(self) -> Dict[str, ToolProviderCredentials]: + """ + returns the credentials schema of the provider + + :return: the credentials schema + """ + if not self.credentials_schema: + return {} + + return self.credentials_schema.copy() + + def user_get_credentails_schema(self) -> UserToolProviderCredentials: + """ + returns the credentials schema of the provider, this method is used for user + + :return: the credentials schema + """ + credentials = self.credentials_schema.copy() + return UserToolProviderCredentials(credentails=credentials) + + def get_tools(self) -> List[Tool]: + """ + returns a list of tools that the provider can provide + + :return: list of tools + """ + return self._get_bulitin_tools() + + def get_tool(self, tool_name: str) -> Tool: + """ + returns the tool that the provider can provide + """ + return next(filter(lambda x: x.identity.name == tool_name, self.get_tools()), None) + + def get_parameters(self, tool_name: str) -> List[ToolParamter]: + """ + returns the parameters of the tool + + :param tool_name: the name of the tool, defined in `get_tools` + :return: list of parameters + """ + tool = next(filter(lambda x: x.identity.name == tool_name, self.get_tools()), None) + if tool is None: + raise ToolNotFoundError(f'tool {tool_name} not found') + return tool.parameters + + @property + def need_credentials(self) -> bool: + """ + returns whether the provider needs credentials + + :return: whether the provider needs credentials + """ + return self.credentials_schema is not None and len(self.credentials_schema) != 0 + + @property + def app_type(self) -> ToolProviderType: + """ + returns the type of the provider + + :return: type of the provider + """ + return ToolProviderType.BUILT_IN + + def validate_parameters(self, tool_id: int, tool_name: str, tool_parameters: Dict[str, Any]) -> None: + """ + validate the parameters of the tool and set the default value if needed + + :param tool_name: the name of the tool, defined in `get_tools` + :param tool_parameters: the parameters of the tool + """ + tool_parameters_schema = self.get_parameters(tool_name) + + tool_parameters_need_to_validate: Dict[str, ToolParamter] = {} + for parameter in tool_parameters_schema: + tool_parameters_need_to_validate[parameter.name] = parameter + + for parameter in tool_parameters: + if parameter not in tool_parameters_need_to_validate: + raise ToolParamterValidationError(f'parameter {parameter} not found in tool {tool_name}') + + # check type + parameter_schema = tool_parameters_need_to_validate[parameter] + if parameter_schema.type == ToolParamter.ToolParameterType.STRING: + if not isinstance(tool_parameters[parameter], str): + raise ToolParamterValidationError(f'parameter {parameter} should be string') + + elif parameter_schema.type == ToolParamter.ToolParameterType.NUMBER: + if not isinstance(tool_parameters[parameter], (int, float)): + raise ToolParamterValidationError(f'parameter {parameter} should be number') + + if parameter_schema.min is not None and tool_parameters[parameter] < parameter_schema.min: + raise ToolParamterValidationError(f'parameter {parameter} should be greater than {parameter_schema.min}') + + if parameter_schema.max is not None and tool_parameters[parameter] > parameter_schema.max: + raise ToolParamterValidationError(f'parameter {parameter} should be less than {parameter_schema.max}') + + elif parameter_schema.type == ToolParamter.ToolParameterType.BOOLEAN: + if not isinstance(tool_parameters[parameter], bool): + raise ToolParamterValidationError(f'parameter {parameter} should be boolean') + + elif parameter_schema.type == ToolParamter.ToolParameterType.SELECT: + if not isinstance(tool_parameters[parameter], str): + raise ToolParamterValidationError(f'parameter {parameter} should be string') + + options = parameter_schema.options + if not isinstance(options, list): + raise ToolParamterValidationError(f'parameter {parameter} options should be list') + + if tool_parameters[parameter] not in [x.value for x in options]: + raise ToolParamterValidationError(f'parameter {parameter} should be one of {options}') + + tool_parameters_need_to_validate.pop(parameter) + + for parameter in tool_parameters_need_to_validate: + parameter_schema = tool_parameters_need_to_validate[parameter] + if parameter_schema.required: + raise ToolParamterValidationError(f'parameter {parameter} is required') + + # the parameter is not set currently, set the default value if needed + if parameter_schema.default is not None: + default_value = parameter_schema.default + # parse default value into the correct type + if parameter_schema.type == ToolParamter.ToolParameterType.STRING or \ + parameter_schema.type == ToolParamter.ToolParameterType.SELECT: + default_value = str(default_value) + elif parameter_schema.type == ToolParamter.ToolParameterType.NUMBER: + default_value = float(default_value) + elif parameter_schema.type == ToolParamter.ToolParameterType.BOOLEAN: + default_value = bool(default_value) + + tool_parameters[parameter] = default_value + + def validate_credentials_format(self, credentials: Dict[str, Any]) -> None: + """ + validate the format of the credentials of the provider and set the default value if needed + + :param credentials: the credentials of the tool + """ + credentials_schema = self.credentials_schema + if credentials_schema is None: + return + + credentials_need_to_validate: Dict[str, ToolProviderCredentials] = {} + for credential_name in credentials_schema: + credentials_need_to_validate[credential_name] = credentials_schema[credential_name] + + for credential_name in credentials: + if credential_name not in credentials_need_to_validate: + raise ToolProviderCredentialValidationError(f'credential {credential_name} not found in provider {self.identity.name}') + + # check type + credential_schema = credentials_need_to_validate[credential_name] + if credential_schema == ToolProviderCredentials.CredentialsType.SECRET_INPUT or \ + credential_schema == ToolProviderCredentials.CredentialsType.TEXT_INPUT: + if not isinstance(credentials[credential_name], str): + raise ToolProviderCredentialValidationError(f'credential {credential_name} should be string') + + elif credential_schema.type == ToolProviderCredentials.CredentialsType.SELECT: + if not isinstance(credentials[credential_name], str): + raise ToolProviderCredentialValidationError(f'credential {credential_name} should be string') + + options = credential_schema.options + if not isinstance(options, list): + raise ToolProviderCredentialValidationError(f'credential {credential_name} options should be list') + + if credentials[credential_name] not in [x.value for x in options]: + raise ToolProviderCredentialValidationError(f'credential {credential_name} should be one of {options}') + + credentials_need_to_validate.pop(credential_name) + + for credential_name in credentials_need_to_validate: + credential_schema = credentials_need_to_validate[credential_name] + if credential_schema.required: + raise ToolProviderCredentialValidationError(f'credential {credential_name} is required') + + # the credential is not set currently, set the default value if needed + if credential_schema.default is not None: + default_value = credential_schema.default + # parse default value into the correct type + if credential_schema.type == ToolProviderCredentials.CredentialsType.SECRET_INPUT or \ + credential_schema.type == ToolProviderCredentials.CredentialsType.TEXT_INPUT or \ + credential_schema.type == ToolProviderCredentials.CredentialsType.SELECT: + default_value = str(default_value) + + credentials[credential_name] = default_value + + def validate_credentials(self, credentials: Dict[str, Any]) -> None: + """ + validate the credentials of the provider + + :param tool_name: the name of the tool, defined in `get_tools` + :param credentials: the credentials of the tool + """ + # validate credentials format + self.validate_credentials_format(credentials) + + # validate credentials + self._validate_credentials(credentials) + + @abstractmethod + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + """ + validate the credentials of the provider + + :param tool_name: the name of the tool, defined in `get_tools` + :param credentials: the credentials of the tool + """ + pass \ No newline at end of file diff --git a/api/core/tools/provider/tool_provider.py b/api/core/tools/provider/tool_provider.py new file mode 100644 index 000000000..722b1662a --- /dev/null +++ b/api/core/tools/provider/tool_provider.py @@ -0,0 +1,218 @@ +from abc import ABC, abstractmethod +from typing import List, Dict, Any, Optional + +from pydantic import BaseModel + +from core.tools.entities.tool_entities import ToolProviderType, \ + ToolProviderIdentity, ToolParamter, ToolProviderCredentials +from core.tools.tool.tool import Tool +from core.tools.entities.user_entities import UserToolProviderCredentials +from core.tools.errors import ToolNotFoundError, \ + ToolParamterValidationError, ToolProviderCredentialValidationError + +class ToolProviderController(BaseModel, ABC): + identity: Optional[ToolProviderIdentity] = None + tools: Optional[List[Tool]] = None + credentials_schema: Optional[Dict[str, ToolProviderCredentials]] = None + + def get_credentails_schema(self) -> Dict[str, ToolProviderCredentials]: + """ + returns the credentials schema of the provider + + :return: the credentials schema + """ + return self.credentials_schema.copy() + + def user_get_credentails_schema(self) -> UserToolProviderCredentials: + """ + returns the credentials schema of the provider, this method is used for user + + :return: the credentials schema + """ + credentials = self.credentials_schema.copy() + return UserToolProviderCredentials(credentails=credentials) + + @abstractmethod + def get_tools(self) -> List[Tool]: + """ + returns a list of tools that the provider can provide + + :return: list of tools + """ + pass + + @abstractmethod + def get_tool(self, tool_name: str) -> Tool: + """ + returns a tool that the provider can provide + + :return: tool + """ + pass + + def get_parameters(self, tool_name: str) -> List[ToolParamter]: + """ + returns the parameters of the tool + + :param tool_name: the name of the tool, defined in `get_tools` + :return: list of parameters + """ + tool = next(filter(lambda x: x.identity.name == tool_name, self.get_tools()), None) + if tool is None: + raise ToolNotFoundError(f'tool {tool_name} not found') + return tool.parameters + + @property + def app_type(self) -> ToolProviderType: + """ + returns the type of the provider + + :return: type of the provider + """ + return ToolProviderType.BUILT_IN + + def validate_parameters(self, tool_id: int, tool_name: str, tool_parameters: Dict[str, Any]) -> None: + """ + validate the parameters of the tool and set the default value if needed + + :param tool_name: the name of the tool, defined in `get_tools` + :param tool_parameters: the parameters of the tool + """ + tool_parameters_schema = self.get_parameters(tool_name) + + tool_parameters_need_to_validate: Dict[str, ToolParamter] = {} + for parameter in tool_parameters_schema: + tool_parameters_need_to_validate[parameter.name] = parameter + + for parameter in tool_parameters: + if parameter not in tool_parameters_need_to_validate: + raise ToolParamterValidationError(f'parameter {parameter} not found in tool {tool_name}') + + # check type + parameter_schema = tool_parameters_need_to_validate[parameter] + if parameter_schema.type == ToolParamter.ToolParameterType.STRING: + if not isinstance(tool_parameters[parameter], str): + raise ToolParamterValidationError(f'parameter {parameter} should be string') + + elif parameter_schema.type == ToolParamter.ToolParameterType.NUMBER: + if not isinstance(tool_parameters[parameter], (int, float)): + raise ToolParamterValidationError(f'parameter {parameter} should be number') + + if parameter_schema.min is not None and tool_parameters[parameter] < parameter_schema.min: + raise ToolParamterValidationError(f'parameter {parameter} should be greater than {parameter_schema.min}') + + if parameter_schema.max is not None and tool_parameters[parameter] > parameter_schema.max: + raise ToolParamterValidationError(f'parameter {parameter} should be less than {parameter_schema.max}') + + elif parameter_schema.type == ToolParamter.ToolParameterType.BOOLEAN: + if not isinstance(tool_parameters[parameter], bool): + raise ToolParamterValidationError(f'parameter {parameter} should be boolean') + + elif parameter_schema.type == ToolParamter.ToolParameterType.SELECT: + if not isinstance(tool_parameters[parameter], str): + raise ToolParamterValidationError(f'parameter {parameter} should be string') + + options = parameter_schema.options + if not isinstance(options, list): + raise ToolParamterValidationError(f'parameter {parameter} options should be list') + + if tool_parameters[parameter] not in [x.value for x in options]: + raise ToolParamterValidationError(f'parameter {parameter} should be one of {options}') + + tool_parameters_need_to_validate.pop(parameter) + + for parameter in tool_parameters_need_to_validate: + parameter_schema = tool_parameters_need_to_validate[parameter] + if parameter_schema.required: + raise ToolParamterValidationError(f'parameter {parameter} is required') + + # the parameter is not set currently, set the default value if needed + if parameter_schema.default is not None: + default_value = parameter_schema.default + # parse default value into the correct type + if parameter_schema.type == ToolParamter.ToolParameterType.STRING or \ + parameter_schema.type == ToolParamter.ToolParameterType.SELECT: + default_value = str(default_value) + elif parameter_schema.type == ToolParamter.ToolParameterType.NUMBER: + default_value = float(default_value) + elif parameter_schema.type == ToolParamter.ToolParameterType.BOOLEAN: + default_value = bool(default_value) + + tool_parameters[parameter] = default_value + + def validate_credentials_format(self, credentials: Dict[str, Any]) -> None: + """ + validate the format of the credentials of the provider and set the default value if needed + + :param credentials: the credentials of the tool + """ + credentials_schema = self.credentials_schema + if credentials_schema is None: + return + + credentials_need_to_validate: Dict[str, ToolProviderCredentials] = {} + for credential_name in credentials_schema: + credentials_need_to_validate[credential_name] = credentials_schema[credential_name] + + for credential_name in credentials: + if credential_name not in credentials_need_to_validate: + raise ToolProviderCredentialValidationError(f'credential {credential_name} not found in provider {self.identity.name}') + + # check type + credential_schema = credentials_need_to_validate[credential_name] + if credential_schema == ToolProviderCredentials.CredentialsType.SECRET_INPUT or \ + credential_schema == ToolProviderCredentials.CredentialsType.TEXT_INPUT: + if not isinstance(credentials[credential_name], str): + raise ToolProviderCredentialValidationError(f'credential {credential_name} should be string') + + elif credential_schema.type == ToolProviderCredentials.CredentialsType.SELECT: + if not isinstance(credentials[credential_name], str): + raise ToolProviderCredentialValidationError(f'credential {credential_name} should be string') + + options = credential_schema.options + if not isinstance(options, list): + raise ToolProviderCredentialValidationError(f'credential {credential_name} options should be list') + + if credentials[credential_name] not in [x.value for x in options]: + raise ToolProviderCredentialValidationError(f'credential {credential_name} should be one of {options}') + + credentials_need_to_validate.pop(credential_name) + + for credential_name in credentials_need_to_validate: + credential_schema = credentials_need_to_validate[credential_name] + if credential_schema.required: + raise ToolProviderCredentialValidationError(f'credential {credential_name} is required') + + # the credential is not set currently, set the default value if needed + if credential_schema.default is not None: + default_value = credential_schema.default + # parse default value into the correct type + if credential_schema.type == ToolProviderCredentials.CredentialsType.SECRET_INPUT or \ + credential_schema.type == ToolProviderCredentials.CredentialsType.TEXT_INPUT or \ + credential_schema.type == ToolProviderCredentials.CredentialsType.SELECT: + default_value = str(default_value) + + credentials[credential_name] = default_value + + def validate_credentials(self, credentials: Dict[str, Any]) -> None: + """ + validate the credentials of the provider + + :param tool_name: the name of the tool, defined in `get_tools` + :param credentials: the credentials of the tool + """ + # validate credentials format + self.validate_credentials_format(credentials) + + # validate credentials + self._validate_credentials(credentials) + + @abstractmethod + def _validate_credentials(self, credentials: Dict[str, Any]) -> None: + """ + validate the credentials of the provider + + :param tool_name: the name of the tool, defined in `get_tools` + :param credentials: the credentials of the tool + """ + pass \ No newline at end of file diff --git a/api/core/tools/tool/api_tool.py b/api/core/tools/tool/api_tool.py new file mode 100644 index 000000000..896adc5b8 --- /dev/null +++ b/api/core/tools/tool/api_tool.py @@ -0,0 +1,222 @@ +from typing import Any, Dict, List, Union +from json import dumps + +from core.tools.entities.tool_bundle import ApiBasedToolBundle +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.tool import Tool +from core.tools.errors import ToolProviderCredentialValidationError + +import httpx +import requests + +class ApiTool(Tool): + api_bundle: ApiBasedToolBundle + + """ + Api tool + """ + def fork_tool_runtime(self, meta: Dict[str, Any]) -> 'Tool': + """ + fork a new tool with meta data + + :param meta: the meta data of a tool call processing, tenant_id is required + :return: the new tool + """ + return self.__class__( + identity=self.identity.copy() if self.identity else None, + parameters=self.parameters.copy() if self.parameters else None, + description=self.description.copy() if self.description else None, + api_bundle=self.api_bundle.copy() if self.api_bundle else None, + runtime=Tool.Runtime(**meta) + ) + + def validate_credentials(self, credentails: Dict[str, Any], parameters: Dict[str, Any], format_only: bool = False) -> None: + """ + validate the credentials for Api tool + """ + # assemble validate request and request parameters + headers = self.assembling_request(parameters) + + if format_only: + return + + response = self.do_http_request(self.api_bundle.server_url, self.api_bundle.method, headers, parameters) + # validate response + self.validate_and_parse_response(response) + + def assembling_request(self, parameters: Dict[str, Any]) -> Dict[str, Any]: + headers = {} + credentials = self.runtime.credentials or {} + + if 'auth_type' not in credentials: + raise ToolProviderCredentialValidationError('Missing auth_type') + + if credentials['auth_type'] == 'api_key': + api_key_header = 'api_key' + + if 'api_key_header' in credentials: + api_key_header = credentials['api_key_header'] + + if 'api_key_value' not in credentials: + raise ToolProviderCredentialValidationError('Missing api_key_value') + + headers[api_key_header] = credentials['api_key_value'] + + needed_parameters = [parameter for parameter in self.api_bundle.parameters if parameter.required] + for parameter in needed_parameters: + if parameter.required and parameter.name not in parameters: + raise ToolProviderCredentialValidationError(f"Missing required parameter {parameter.name}") + + if parameter.default is not None and parameter.name not in parameters: + parameters[parameter.name] = parameter.default + + return headers + + def validate_and_parse_response(self, response: Union[httpx.Response, requests.Response]) -> str: + """ + validate the response + """ + if isinstance(response, httpx.Response): + if response.status_code >= 400: + raise ToolProviderCredentialValidationError(f"Request failed with status code {response.status_code}") + return response.text + elif isinstance(response, requests.Response): + if not response.ok: + raise ToolProviderCredentialValidationError(f"Request failed with status code {response.status_code}") + return response.text + else: + raise ValueError(f'Invalid response type {type(response)}') + + def do_http_request(self, url: str, method: str, headers: Dict[str, Any], parameters: Dict[str, Any]) -> httpx.Response: + """ + do http request depending on api bundle + """ + method = method.lower() + + params = {} + path_params = {} + body = {} + cookies = {} + + # check parameters + for parameter in self.api_bundle.openapi.get('parameters', []): + if parameter['in'] == 'path': + value = '' + if parameter['name'] in parameters: + value = parameters[parameter['name']] + elif parameter['required']: + raise ToolProviderCredentialValidationError(f"Missing required parameter {parameter['name']}") + path_params[parameter['name']] = value + + elif parameter['in'] == 'query': + value = '' + if parameter['name'] in parameters: + value = parameters[parameter['name']] + elif parameter['required']: + raise ToolProviderCredentialValidationError(f"Missing required parameter {parameter['name']}") + params[parameter['name']] = value + + elif parameter['in'] == 'cookie': + value = '' + if parameter['name'] in parameters: + value = parameters[parameter['name']] + elif parameter['required']: + raise ToolProviderCredentialValidationError(f"Missing required parameter {parameter['name']}") + cookies[parameter['name']] = value + + elif parameter['in'] == 'header': + value = '' + if parameter['name'] in parameters: + value = parameters[parameter['name']] + elif parameter['required']: + raise ToolProviderCredentialValidationError(f"Missing required parameter {parameter['name']}") + headers[parameter['name']] = value + + # check if there is a request body and handle it + if 'requestBody' in self.api_bundle.openapi and self.api_bundle.openapi['requestBody'] is not None: + # handle json request body + if 'content' in self.api_bundle.openapi['requestBody']: + for content_type in self.api_bundle.openapi['requestBody']['content']: + headers['Content-Type'] = content_type + body_schema = self.api_bundle.openapi['requestBody']['content'][content_type]['schema'] + required = body_schema['required'] if 'required' in body_schema else [] + properties = body_schema['properties'] if 'properties' in body_schema else {} + for name, property in properties.items(): + if name in parameters: + # convert type + try: + value = parameters[name] + if property['type'] == 'integer': + value = int(value) + elif property['type'] == 'number': + # check if it is a float + if '.' in value: + value = float(value) + else: + value = int(value) + elif property['type'] == 'boolean': + value = bool(value) + body[name] = value + except ValueError as e: + body[name] = parameters[name] + elif name in required: + raise ToolProviderCredentialValidationError( + f"Missing required parameter {name} in operation {self.api_bundle.operation_id}" + ) + elif 'default' in property: + body[name] = property['default'] + else: + body[name] = None + break + + # replace path parameters + for name, value in path_params.items(): + url = url.replace(f'{{{name}}}', value) + + # parse http body data if needed, for GET/HEAD/OPTIONS/TRACE, the body is ignored + if 'Content-Type' in headers: + if headers['Content-Type'] == 'application/json': + body = dumps(body) + else: + body = body + + # do http request + if method == 'get': + response = httpx.get(url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True) + elif method == 'post': + response = httpx.post(url, params=params, headers=headers, cookies=cookies, data=body, timeout=10, follow_redirects=True) + elif method == 'put': + response = httpx.put(url, params=params, headers=headers, cookies=cookies, data=body, timeout=10, follow_redirects=True) + elif method == 'delete': + """ + request body data is unsupported for DELETE method in standard http protocol + however, OpenAPI 3.0 supports request body data for DELETE method, so we support it here by using requests + """ + response = requests.delete(url, params=params, headers=headers, cookies=cookies, data=body, timeout=10, allow_redirects=True) + elif method == 'patch': + response = httpx.patch(url, params=params, headers=headers, cookies=cookies, data=body, timeout=10, follow_redirects=True) + elif method == 'head': + response = httpx.head(url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True) + elif method == 'options': + response = httpx.options(url, params=params, headers=headers, cookies=cookies, timeout=10, follow_redirects=True) + else: + raise ValueError(f'Invalid http method {method}') + + return response + + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) -> ToolInvokeMessage | List[ToolInvokeMessage]: + """ + invoke http request + """ + # assemble request + headers = self.assembling_request(tool_paramters) + + # do http request + response = self.do_http_request(self.api_bundle.server_url, self.api_bundle.method, headers, tool_paramters) + + # validate response + response = self.validate_and_parse_response(response) + + # assemble invoke message + return self.create_text_message(response) + \ No newline at end of file diff --git a/api/core/tools/tool/builtin_tool.py b/api/core/tools/tool/builtin_tool.py new file mode 100644 index 000000000..11116dbad --- /dev/null +++ b/api/core/tools/tool/builtin_tool.py @@ -0,0 +1,140 @@ +from core.tools.tool.tool import Tool +from core.tools.model.tool_model_manager import ToolModelManager +from core.model_runtime.entities.message_entities import PromptMessage +from core.model_runtime.entities.llm_entities import LLMResult +from core.model_runtime.entities.message_entities import SystemPromptMessage, UserPromptMessage +from core.tools.utils.web_reader_tool import get_url + +from typing import List +from enum import Enum + +_SUMMARY_PROMPT = """You are a professional language researcher, you are interested in the language +and you can quickly aimed at the main point of an webpage and reproduce it in your own words but +retain the original meaning and keep the key points. +however, the text you got is too long, what you got is possible a part of the text. +Please summarize the text you got. +""" + + +class BuiltinTool(Tool): + """ + Builtin tool + + :param meta: the meta data of a tool call processing + """ + + def invoke_model( + self, user_id: str, prompt_messages: List[PromptMessage], stop: List[str] + ) -> LLMResult: + """ + invoke model + + :param model_config: the model config + :param prompt_messages: the prompt messages + :param stop: the stop words + :return: the model result + """ + # invoke model + return ToolModelManager.invoke( + user_id=user_id, + tenant_id=self.runtime.tenant_id, + tool_type='builtin', + tool_name=self.identity.name, + prompt_messages=prompt_messages, + ) + + def get_max_tokens(self) -> int: + """ + get max tokens + + :param model_config: the model config + :return: the max tokens + """ + return ToolModelManager.get_max_llm_context_tokens( + tenant_id=self.runtime.tenant_id, + ) + + def get_prompt_tokens(self, prompt_messages: List[PromptMessage]) -> int: + """ + get prompt tokens + + :param prompt_messages: the prompt messages + :return: the tokens + """ + return ToolModelManager.calculate_tokens( + tenant_id=self.runtime.tenant_id, + prompt_messages=prompt_messages + ) + + def summary(self, user_id: str, content: str) -> str: + max_tokens = self.get_max_tokens() + + if self.get_prompt_tokens(prompt_messages=[ + UserPromptMessage(content=content) + ]) < max_tokens * 0.6: + return content + + def get_prompt_tokens(content: str) -> int: + return self.get_prompt_tokens(prompt_messages=[ + SystemPromptMessage(content=_SUMMARY_PROMPT), + UserPromptMessage(content=content) + ]) + + def summarize(content: str) -> str: + summary = self.invoke_model(user_id=user_id, prompt_messages=[ + SystemPromptMessage(content=_SUMMARY_PROMPT), + UserPromptMessage(content=content) + ], stop=[]) + + return summary.message.content + + lines = content.split('\n') + new_lines = [] + # split long line into multiple lines + for i in range(len(lines)): + line = lines[i] + if not line.strip(): + continue + if len(line) < max_tokens * 0.5: + new_lines.append(line) + elif get_prompt_tokens(line) > max_tokens * 0.7: + while get_prompt_tokens(line) > max_tokens * 0.7: + new_lines.append(line[:int(max_tokens * 0.5)]) + line = line[int(max_tokens * 0.5):] + new_lines.append(line) + else: + new_lines.append(line) + + # merge lines into messages with max tokens + messages: List[str] = [] + for i in new_lines: + if len(messages) == 0: + messages.append(i) + else: + if len(messages[-1]) + len(i) < max_tokens * 0.5: + messages[-1] += i + if get_prompt_tokens(messages[-1] + i) > max_tokens * 0.7: + messages.append(i) + else: + messages[-1] += i + + summaries = [] + for i in range(len(messages)): + message = messages[i] + summary = summarize(message) + summaries.append(summary) + + result = '\n'.join(summaries) + + if self.get_prompt_tokens(prompt_messages=[ + UserPromptMessage(content=result) + ]) > max_tokens * 0.7: + return self.summary(user_id=user_id, content=result) + + return result + + def get_url(self, url: str, user_agent: str = None) -> str: + """ + get url + """ + return get_url(url, user_agent=user_agent) \ No newline at end of file diff --git a/api/core/tool/dataset_multi_retriever_tool.py b/api/core/tools/tool/dataset_retriever/dataset_multi_retriever_tool.py similarity index 99% rename from api/core/tool/dataset_multi_retriever_tool.py rename to api/core/tools/tool/dataset_retriever/dataset_multi_retriever_tool.py index c9ca7eb04..e20540168 100644 --- a/api/core/tool/dataset_multi_retriever_tool.py +++ b/api/core/tools/tool/dataset_retriever/dataset_multi_retriever_tool.py @@ -246,4 +246,4 @@ class DatasetMultiRetrieverTool(BaseTool): for thread in threads: thread.join() - all_documents.extend(documents) + all_documents.extend(documents) \ No newline at end of file diff --git a/api/core/tool/dataset_retriever_tool.py b/api/core/tools/tool/dataset_retriever/dataset_retriever_tool.py similarity index 99% rename from api/core/tool/dataset_retriever_tool.py rename to api/core/tools/tool/dataset_retriever/dataset_retriever_tool.py index 9049b5e69..79de38ca1 100644 --- a/api/core/tool/dataset_retriever_tool.py +++ b/api/core/tools/tool/dataset_retriever/dataset_retriever_tool.py @@ -233,4 +233,4 @@ class DatasetRetrieverTool(BaseTool): return str("\n".join(document_context_list)) async def _arun(self, tool_input: str) -> str: - raise NotImplementedError() + raise NotImplementedError() \ No newline at end of file diff --git a/api/core/tools/tool/dataset_retriever_tool.py b/api/core/tools/tool/dataset_retriever_tool.py new file mode 100644 index 000000000..800952226 --- /dev/null +++ b/api/core/tools/tool/dataset_retriever_tool.py @@ -0,0 +1,95 @@ +from typing import Any, Dict, List, Union +from core.features.dataset_retrieval import DatasetRetrievalFeature +from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter, ToolIdentity, ToolDescription +from core.tools.tool.tool import Tool +from core.tools.entities.common_entities import I18nObject +from core.callback_handler.index_tool_callback_handler import DatasetIndexToolCallbackHandler +from core.entities.application_entities import DatasetRetrieveConfigEntity, InvokeFrom + +from langchain.tools import BaseTool + +class DatasetRetrieverTool(Tool): + langchain_tool: BaseTool + + @staticmethod + def get_dataset_tools(tenant_id: str, + dataset_ids: list[str], + retrieve_config: DatasetRetrieveConfigEntity, + return_resource: bool, + invoke_from: InvokeFrom, + hit_callback: DatasetIndexToolCallbackHandler + ) -> List['DatasetRetrieverTool']: + """ + get dataset tool + """ + # check if retrieve_config is valid + if dataset_ids is None or len(dataset_ids) == 0: + return [] + if retrieve_config is None: + return [] + + feature = DatasetRetrievalFeature() + + # save original retrieve strategy, and set retrieve strategy to SINGLE + # Agent only support SINGLE mode + original_retriever_mode = retrieve_config.retrieve_strategy + retrieve_config.retrieve_strategy = DatasetRetrieveConfigEntity.RetrieveStrategy.SINGLE + langchain_tools = feature.to_dataset_retriever_tool( + tenant_id=tenant_id, + dataset_ids=dataset_ids, + retrieve_config=retrieve_config, + return_resource=return_resource, + invoke_from=invoke_from, + hit_callback=hit_callback + ) + # restore retrieve strategy + retrieve_config.retrieve_strategy = original_retriever_mode + + # convert langchain tools to Tools + tools = [] + for langchain_tool in langchain_tools: + tool = DatasetRetrieverTool( + langchain_tool=langchain_tool, + identity=ToolIdentity(author='', name=langchain_tool.name, label=I18nObject(en_US='', zh_Hans='')), + parameters=[], + is_team_authorization=True, + description=ToolDescription( + human=I18nObject(en_US='', zh_Hans=''), + llm=langchain_tool.description), + runtime=DatasetRetrieverTool.Runtime() + ) + + tools.append(tool) + + return tools + + def get_runtime_parameters(self) -> List[ToolParamter]: + return [ + ToolParamter(name='query', + label=I18nObject(en_US='', zh_Hans=''), + human_description=I18nObject(en_US='', zh_Hans=''), + type=ToolParamter.ToolParameterType.STRING, + form=ToolParamter.ToolParameterForm.LLM, + llm_description='Query for the dataset to be used to retrieve the dataset.', + required=True, + default=''), + ] + + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) -> ToolInvokeMessage | List[ToolInvokeMessage]: + """ + invoke dataset retriever tool + """ + query = tool_paramters.get('query', None) + if not query: + return self.create_text_message(text='please input query') + + # invoke dataset retriever tool + result = self.langchain_tool._run(query=query) + + return self.create_text_message(text=result) + + def validate_credentials(self, credentails: Dict[str, Any], parameters: Dict[str, Any]) -> None: + """ + validate the credentials for dataset retriever tool + """ + pass \ No newline at end of file diff --git a/api/core/tools/tool/tool.py b/api/core/tools/tool/tool.py new file mode 100644 index 000000000..4e29b427a --- /dev/null +++ b/api/core/tools/tool/tool.py @@ -0,0 +1,302 @@ +from pydantic import BaseModel + +from typing import List, Dict, Any, Union, Optional +from abc import abstractmethod, ABC +from enum import Enum + +from core.tools.entities.tool_entities import ToolIdentity, ToolInvokeMessage,\ + ToolParamter, ToolDescription, ToolRuntimeVariablePool, ToolRuntimeVariable, ToolRuntimeImageVariable +from core.tools.tool_file_manager import ToolFileManager +from core.callback_handler.agent_tool_callback_handler import DifyAgentCallbackHandler + +class Tool(BaseModel, ABC): + identity: ToolIdentity = None + parameters: Optional[List[ToolParamter]] = None + description: ToolDescription = None + is_team_authorization: bool = False + agent_callback: Optional[DifyAgentCallbackHandler] = None + use_callback: bool = False + + class Runtime(BaseModel): + """ + Meta data of a tool call processing + """ + def __init__(self, **data: Any): + super().__init__(**data) + if not self.runtime_parameters: + self.runtime_parameters = {} + + tenant_id: str = None + tool_id: str = None + credentials: Dict[str, Any] = None + runtime_parameters: Dict[str, Any] = None + + runtime: Runtime = None + variables: ToolRuntimeVariablePool = None + + def __init__(self, **data: Any): + super().__init__(**data) + + if not self.agent_callback: + self.use_callback = False + else: + self.use_callback = True + + class VARIABLE_KEY(Enum): + IMAGE = 'image' + + def fork_tool_runtime(self, meta: Dict[str, Any], agent_callback: DifyAgentCallbackHandler = None) -> 'Tool': + """ + fork a new tool with meta data + + :param meta: the meta data of a tool call processing, tenant_id is required + :return: the new tool + """ + return self.__class__( + identity=self.identity.copy() if self.identity else None, + parameters=self.parameters.copy() if self.parameters else None, + description=self.description.copy() if self.description else None, + runtime=Tool.Runtime(**meta), + agent_callback=agent_callback + ) + + def load_variables(self, variables: ToolRuntimeVariablePool): + """ + load variables from database + + :param conversation_id: the conversation id + """ + self.variables = variables + + def set_image_variable(self, variable_name: str, image_key: str) -> None: + """ + set an image variable + """ + if not self.variables: + return + + self.variables.set_file(self.identity.name, variable_name, image_key) + + def set_text_variable(self, variable_name: str, text: str) -> None: + """ + set a text variable + """ + if not self.variables: + return + + self.variables.set_text(self.identity.name, variable_name, text) + + def get_variable(self, name: Union[str, Enum]) -> Optional[ToolRuntimeVariable]: + """ + get a variable + + :param name: the name of the variable + :return: the variable + """ + if not self.variables: + return None + + if isinstance(name, Enum): + name = name.value + + for variable in self.variables.pool: + if variable.name == name: + return variable + + return None + + def get_default_image_variable(self) -> Optional[ToolRuntimeVariable]: + """ + get the default image variable + + :return: the image variable + """ + if not self.variables: + return None + + return self.get_variable(self.VARIABLE_KEY.IMAGE) + + def get_variable_file(self, name: Union[str, Enum]) -> Optional[bytes]: + """ + get a variable file + + :param name: the name of the variable + :return: the variable file + """ + variable = self.get_variable(name) + if not variable: + return None + + if not isinstance(variable, ToolRuntimeImageVariable): + return None + + message_file_id = variable.value + # get file binary + file_binary = ToolFileManager.get_file_binary_by_message_file_id(message_file_id) + if not file_binary: + return None + + return file_binary[0] + + def list_variables(self) -> List[ToolRuntimeVariable]: + """ + list all variables + + :return: the variables + """ + if not self.variables: + return [] + + return self.variables.pool + + def list_default_image_variables(self) -> List[ToolRuntimeVariable]: + """ + list all image variables + + :return: the image variables + """ + if not self.variables: + return [] + + result = [] + + for variable in self.variables.pool: + if variable.name.startswith(self.VARIABLE_KEY.IMAGE.value): + result.append(variable) + + return result + + def invoke(self, user_id: str, tool_paramters: Dict[str, Any]) -> List[ToolInvokeMessage]: + # update tool_paramters + if self.runtime.runtime_parameters: + tool_paramters.update(self.runtime.runtime_parameters) + + # hit callback + if self.use_callback: + self.agent_callback.on_tool_start( + tool_name=self.identity.name, + tool_inputs=tool_paramters + ) + + try: + result = self._invoke( + user_id=user_id, + tool_paramters=tool_paramters, + ) + except Exception as e: + if self.use_callback: + self.agent_callback.on_tool_error(e) + raise e + + if not isinstance(result, list): + result = [result] + + # hit callback + if self.use_callback: + self.agent_callback.on_tool_end( + tool_name=self.identity.name, + tool_inputs=tool_paramters, + tool_outputs=self._convert_tool_response_to_str(result) + ) + + return result + + def _convert_tool_response_to_str(self, tool_response: List[ToolInvokeMessage]) -> str: + """ + Handle tool response + """ + result = '' + for response in tool_response: + if response.type == ToolInvokeMessage.MessageType.TEXT: + result += response.message + elif response.type == ToolInvokeMessage.MessageType.LINK: + result += f"result link: {response.message}. please dirct user to check it." + elif response.type == ToolInvokeMessage.MessageType.IMAGE_LINK or \ + response.type == ToolInvokeMessage.MessageType.IMAGE: + result += f"image has been created and sent to user already, you should tell user to check it now." + elif response.type == ToolInvokeMessage.MessageType.BLOB: + if len(response.message) > 114: + result += str(response.message[:114]) + '...' + else: + result += str(response.message) + else: + result += f"tool response: {response.message}." + + return result + + @abstractmethod + def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]: + pass + + def validate_credentials(self, credentails: Dict[str, Any], parameters: Dict[str, Any]) -> None: + """ + validate the credentials + + :param credentails: the credentials + :param parameters: the parameters + """ + pass + + def get_runtime_parameters(self) -> List[ToolParamter]: + """ + get the runtime parameters + + interface for developer to dynamic change the parameters of a tool depends on the variables pool + + :return: the runtime parameters + """ + return self.parameters + + def is_tool_avaliable(self) -> bool: + """ + check if the tool is avaliable + + :return: if the tool is avaliable + """ + return True + + def create_image_message(self, image: str, save_as: str = '') -> ToolInvokeMessage: + """ + create an image message + + :param image: the url of the image + :return: the image message + """ + return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.IMAGE, + message=image, + save_as=save_as) + + def create_link_message(self, link: str, save_as: str = '') -> ToolInvokeMessage: + """ + create a link message + + :param link: the url of the link + :return: the link message + """ + return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.LINK, + message=link, + save_as=save_as) + + def create_text_message(self, text: str, save_as: str = '') -> ToolInvokeMessage: + """ + create a text message + + :param text: the text + :return: the text message + """ + return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.TEXT, + message=text, + save_as=save_as + ) + + def create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = '') -> ToolInvokeMessage: + """ + create a blob message + + :param blob: the blob + :return: the blob message + """ + return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.BLOB, + message=blob, meta=meta, + save_as=save_as + ) \ No newline at end of file diff --git a/api/core/tools/tool_file_manager.py b/api/core/tools/tool_file_manager.py new file mode 100644 index 000000000..43d74622a --- /dev/null +++ b/api/core/tools/tool_file_manager.py @@ -0,0 +1,197 @@ +import logging +import time +import os +import hmac +import base64 +import hashlib + +from typing import Union, Tuple, Generator +from uuid import uuid4 +from mimetypes import guess_extension, guess_type +from httpx import get + +from flask import current_app + +from models.tools import ToolFile +from models.model import MessageFile + +from extensions.ext_database import db +from extensions.ext_storage import storage + +logger = logging.getLogger(__name__) + +class ToolFileManager: + @staticmethod + def sign_file(file_id: str, extension: str) -> str: + """ + sign file to get a temporary url + """ + base_url = current_app.config.get('FILES_URL') + file_preview_url = f'{base_url}/files/tools/{file_id}{extension}' + + timestamp = str(int(time.time())) + nonce = os.urandom(16).hex() + data_to_sign = f"file-preview|{file_id}|{timestamp}|{nonce}" + secret_key = current_app.config['SECRET_KEY'].encode() + sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() + encoded_sign = base64.urlsafe_b64encode(sign).decode() + + return f"{file_preview_url}?timestamp={timestamp}&nonce={nonce}&sign={encoded_sign}" + + @staticmethod + def verify_file(file_id: str, timestamp: str, nonce: str, sign: str) -> bool: + """ + verify signature + """ + data_to_sign = f"file-preview|{file_id}|{timestamp}|{nonce}" + secret_key = current_app.config['SECRET_KEY'].encode() + recalculated_sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() + recalculated_encoded_sign = base64.urlsafe_b64encode(recalculated_sign).decode() + + # verify signature + if sign != recalculated_encoded_sign: + return False + + current_time = int(time.time()) + return current_time - int(timestamp) <= 300 # expired after 5 minutes + + @staticmethod + def create_file_by_raw(user_id: str, tenant_id: str, + conversation_id: str, file_binary: bytes, + mimetype: str + ) -> ToolFile: + """ + create file + """ + extension = guess_extension(mimetype) or '.bin' + unique_name = uuid4().hex + filename = f"/tools/{tenant_id}/{unique_name}{extension}" + storage.save(filename, file_binary) + + tool_file = ToolFile(user_id=user_id, tenant_id=tenant_id, + conversation_id=conversation_id, file_key=filename, mimetype=mimetype) + + db.session.add(tool_file) + db.session.commit() + + return tool_file + + @staticmethod + def create_file_by_url(user_id: str, tenant_id: str, + conversation_id: str, file_url: str, + ) -> ToolFile: + """ + create file + """ + # try to download image + response = get(file_url) + response.raise_for_status() + blob = response.content + mimetype = guess_type(file_url)[0] or 'octet/stream' + extension = guess_extension(mimetype) or '.bin' + unique_name = uuid4().hex + filename = f"/tools/{tenant_id}/{unique_name}{extension}" + storage.save(filename, blob) + + tool_file = ToolFile(user_id=user_id, tenant_id=tenant_id, + conversation_id=conversation_id, file_key=filename, + mimetype=mimetype, original_url=file_url) + + db.session.add(tool_file) + db.session.commit() + + return tool_file + + @staticmethod + def create_file_by_key(user_id: str, tenant_id: str, + conversation_id: str, file_key: str, + mimetype: str + ) -> ToolFile: + """ + create file + """ + tool_file = ToolFile(user_id=user_id, tenant_id=tenant_id, + conversation_id=conversation_id, file_key=file_key, mimetype=mimetype) + return tool_file + + @staticmethod + def get_file_binary(id: str) -> Union[Tuple[bytes, str], None]: + """ + get file binary + + :param id: the id of the file + + :return: the binary of the file, mime type + """ + tool_file: ToolFile = db.session.query(ToolFile).filter( + ToolFile.id == id, + ).first() + + if not tool_file: + return None + + blob = storage.load_once(tool_file.file_key) + + return blob, tool_file.mimetype + + @staticmethod + def get_file_binary_by_message_file_id(id: str) -> Union[Tuple[bytes, str], None]: + """ + get file binary + + :param id: the id of the file + + :return: the binary of the file, mime type + """ + message_file: MessageFile = db.session.query(MessageFile).filter( + MessageFile.id == id, + ).first() + + # get tool file id + tool_file_id = message_file.url.split('/')[-1] + # trim extension + tool_file_id = tool_file_id.split('.')[0] + + tool_file: ToolFile = db.session.query(ToolFile).filter( + ToolFile.id == tool_file_id, + ).first() + + if not tool_file: + return None + + blob = storage.load_once(tool_file.file_key) + + return blob, tool_file.mimetype + + @staticmethod + def get_file_generator_by_message_file_id(id: str) -> Union[Tuple[Generator, str], None]: + """ + get file binary + + :param id: the id of the file + + :return: the binary of the file, mime type + """ + message_file: MessageFile = db.session.query(MessageFile).filter( + MessageFile.id == id, + ).first() + + # get tool file id + tool_file_id = message_file.url.split('/')[-1] + # trim extension + tool_file_id = tool_file_id.split('.')[0] + + tool_file: ToolFile = db.session.query(ToolFile).filter( + ToolFile.id == tool_file_id, + ).first() + + if not tool_file: + return None + + generator = storage.load_stream(tool_file.file_key) + + return generator, tool_file.mimetype + +# init tool_file_parser +from core.file.tool_file_parser import tool_file_manager +tool_file_manager['manager'] = ToolFileManager diff --git a/api/core/tools/tool_manager.py b/api/core/tools/tool_manager.py new file mode 100644 index 000000000..4b88d9b9e --- /dev/null +++ b/api/core/tools/tool_manager.py @@ -0,0 +1,448 @@ +from typing import List, Dict, Any, Tuple, Union +from os import listdir, path + +from core.tools.entities.tool_entities import ToolInvokeMessage, ApiProviderAuthType, ToolProviderCredentials +from core.tools.provider.tool_provider import ToolProviderController +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.tool.api_tool import ApiTool +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.entities.constant import DEFAULT_PROVIDERS +from core.tools.entities.common_entities import I18nObject +from core.tools.errors import ToolProviderNotFoundError +from core.tools.provider.api_tool_provider import ApiBasedToolProviderController +from core.tools.provider.app_tool_provider import AppBasedToolProviderEntity +from core.tools.entities.user_entities import UserToolProvider +from core.tools.utils.configration import ToolConfiguration +from core.tools.utils.encoder import serialize_base_model_dict +from core.tools.provider.builtin._positions import BuiltinToolProviderSort + +from core.model_runtime.entities.message_entities import PromptMessage +from core.callback_handler.agent_tool_callback_handler import DifyAgentCallbackHandler + +from extensions.ext_database import db + +from models.tools import ApiToolProvider, BuiltinToolProvider + +import importlib +import logging +import json +import mimetypes + +logger = logging.getLogger(__name__) + +_builtin_providers = {} + +class ToolManager: + @staticmethod + def invoke( + provider: str, + tool_id: str, + tool_name: str, + tool_parameters: Dict[str, Any], + credentials: Dict[str, Any], + prompt_messages: List[PromptMessage], + ) -> List[ToolInvokeMessage]: + """ + invoke the assistant + + :param provider: the name of the provider + :param tool_id: the id of the tool + :param tool_name: the name of the tool, defined in `get_tools` + :param tool_parameters: the parameters of the tool + :param credentials: the credentials of the tool + :param prompt_messages: the prompt messages that the tool can use + + :return: the messages that the tool wants to send to the user + """ + provider_entity: ToolProviderController = None + if provider == DEFAULT_PROVIDERS.API_BASED: + provider_entity = ApiBasedToolProviderController() + elif provider == DEFAULT_PROVIDERS.APP_BASED: + provider_entity = AppBasedToolProviderEntity() + + if provider_entity is None: + # fetch the provider from .provider.builtin + py_path = path.join(path.dirname(path.realpath(__file__)), 'builtin', provider, f'{provider}.py') + spec = importlib.util.spec_from_file_location(f'core.tools.provider.builtin.{provider}.{provider}', py_path) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + + # get all the classes in the module + classes = [ x for _, x in vars(mod).items() + if isinstance(x, type) and x != ToolProviderController and issubclass(x, ToolProviderController) + ] + if len(classes) == 0: + raise ToolProviderNotFoundError(f'provider {provider} not found') + if len(classes) > 1: + raise ToolProviderNotFoundError(f'multiple providers found for {provider}') + + provider_entity = classes[0]() + + return provider_entity.invoke(tool_id, tool_name, tool_parameters, credentials, prompt_messages) + + @staticmethod + def get_builtin_provider(provider: str) -> BuiltinToolProviderController: + global _builtin_providers + """ + get the builtin provider + + :param provider: the name of the provider + :return: the provider + """ + if len(_builtin_providers) == 0: + # init the builtin providers + ToolManager.list_builtin_providers() + + if provider not in _builtin_providers: + raise ToolProviderNotFoundError(f'builtin provider {provider} not found') + + return _builtin_providers[provider] + + @staticmethod + def get_builtin_tool(provider: str, tool_name: str) -> BuiltinTool: + """ + get the builtin tool + + :param provider: the name of the provider + :param tool_name: the name of the tool + + :return: the provider, the tool + """ + provider_controller = ToolManager.get_builtin_provider(provider) + tool = provider_controller.get_tool(tool_name) + + return tool + + @staticmethod + def get_tool(provider_type: str, provider_id: str, tool_name: str, tanent_id: str = None) \ + -> Union[BuiltinTool, ApiTool]: + """ + get the tool + + :param provider_type: the type of the provider + :param provider_name: the name of the provider + :param tool_name: the name of the tool + + :return: the tool + """ + if provider_type == 'builtin': + return ToolManager.get_builtin_tool(provider_id, tool_name) + elif provider_type == 'api': + if tanent_id is None: + raise ValueError('tanent id is required for api provider') + api_provider, _ = ToolManager.get_api_provider_controller(tanent_id, provider_id) + return api_provider.get_tool(tool_name) + elif provider_type == 'app': + raise NotImplementedError('app provider not implemented') + else: + raise ToolProviderNotFoundError(f'provider type {provider_type} not found') + + @staticmethod + def get_tool_runtime(provider_type: str, provider_name: str, tool_name: str, tanent_id, + agent_callback: DifyAgentCallbackHandler = None) \ + -> Union[BuiltinTool, ApiTool]: + """ + get the tool runtime + + :param provider_type: the type of the provider + :param provider_name: the name of the provider + :param tool_name: the name of the tool + + :return: the tool + """ + if provider_type == 'builtin': + builtin_tool = ToolManager.get_builtin_tool(provider_name, tool_name) + + # check if the builtin tool need credentials + provider_controller = ToolManager.get_builtin_provider(provider_name) + if not provider_controller.need_credentials: + return builtin_tool.fork_tool_runtime(meta={ + 'tenant_id': tanent_id, + 'credentials': {}, + }, agent_callback=agent_callback) + + # get credentials + builtin_provider: BuiltinToolProvider = db.session.query(BuiltinToolProvider).filter( + BuiltinToolProvider.tenant_id == tanent_id, + BuiltinToolProvider.provider == provider_name, + ).first() + + if builtin_provider is None: + raise ToolProviderNotFoundError(f'builtin provider {provider_name} not found') + + # decrypt the credentials + credentials = builtin_provider.credentials + controller = ToolManager.get_builtin_provider(provider_name) + tool_configuration = ToolConfiguration(tenant_id=tanent_id, provider_controller=controller) + + decrypted_credentails = tool_configuration.decrypt_tool_credentials(credentials) + + return builtin_tool.fork_tool_runtime(meta={ + 'tenant_id': tanent_id, + 'credentials': decrypted_credentails, + 'runtime_parameters': {} + }, agent_callback=agent_callback) + + elif provider_type == 'api': + if tanent_id is None: + raise ValueError('tanent id is required for api provider') + + api_provider, credentials = ToolManager.get_api_provider_controller(tanent_id, provider_name) + + # decrypt the credentials + tool_configuration = ToolConfiguration(tenant_id=tanent_id, provider_controller=api_provider) + decrypted_credentails = tool_configuration.decrypt_tool_credentials(credentials) + + return api_provider.get_tool(tool_name).fork_tool_runtime(meta={ + 'tenant_id': tanent_id, + 'credentials': decrypted_credentails, + }) + elif provider_type == 'app': + raise NotImplementedError('app provider not implemented') + else: + raise ToolProviderNotFoundError(f'provider type {provider_type} not found') + + @staticmethod + def get_builtin_provider_icon(provider: str) -> Tuple[str, str]: + """ + get the absolute path of the icon of the builtin provider + + :param provider: the name of the provider + + :return: the absolute path of the icon, the mime type of the icon + """ + # get provider + provider_controller = ToolManager.get_builtin_provider(provider) + + absolute_path = path.join(path.dirname(path.realpath(__file__)), 'provider', 'builtin', provider, '_assets', provider_controller.identity.icon) + # check if the icon exists + if not path.exists(absolute_path): + raise ToolProviderNotFoundError(f'builtin provider {provider} icon not found') + + # get the mime type + mime_type, _ = mimetypes.guess_type(absolute_path) + mime_type = mime_type or 'application/octet-stream' + + return absolute_path, mime_type + + @staticmethod + def list_builtin_providers() -> List[BuiltinToolProviderController]: + global _builtin_providers + + # use cache first + if len(_builtin_providers) > 0: + return list(_builtin_providers.values()) + + builtin_providers = [] + for provider in listdir(path.join(path.dirname(path.realpath(__file__)), 'provider', 'builtin')): + if provider.startswith('__'): + continue + + if path.isdir(path.join(path.dirname(path.realpath(__file__)), 'provider', 'builtin', provider)): + if provider.startswith('__'): + continue + + py_path = path.join(path.dirname(path.realpath(__file__)), 'provider', 'builtin', provider, f'{provider}.py') + spec = importlib.util.spec_from_file_location(f'core.tools.provider.builtin.{provider}.{provider}', py_path) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + + # load all classes + classes = [ + obj for name, obj in vars(mod).items() + if isinstance(obj, type) and obj != BuiltinToolProviderController and issubclass(obj, BuiltinToolProviderController) + ] + if len(classes) == 0: + raise ToolProviderNotFoundError(f'provider {provider} not found') + if len(classes) > 1: + raise ToolProviderNotFoundError(f'multiple providers found for {provider}') + + # init provider + provider_class = classes[0] + builtin_providers.append(provider_class()) + + # cache the builtin providers + for provider in builtin_providers: + _builtin_providers[provider.identity.name] = provider + return builtin_providers + + @staticmethod + def user_list_providers( + user_id: str, + tenant_id: str, + ) -> List[UserToolProvider]: + result_providers: Dict[str, UserToolProvider] = {} + # get builtin providers + builtin_providers = ToolManager.list_builtin_providers() + # append builtin providers + for provider in builtin_providers: + result_providers[provider.identity.name] = UserToolProvider( + id=provider.identity.name, + author=provider.identity.author, + name=provider.identity.name, + description=I18nObject( + en_US=provider.identity.description.en_US, + zh_Hans=provider.identity.description.zh_Hans, + ), + icon=provider.identity.icon, + label=I18nObject( + en_US=provider.identity.label.en_US, + zh_Hans=provider.identity.label.zh_Hans, + ), + type=UserToolProvider.ProviderType.BUILTIN, + team_credentials={}, + is_team_authorization=False, + ) + + # get credentials schema + schema = provider.get_credentails_schema() + for name, value in schema.items(): + result_providers[provider.identity.name].team_credentials[name] = \ + ToolProviderCredentials.CredentialsType.defaut(value.type) + + # check if the provider need credentials + if not provider.need_credentials: + result_providers[provider.identity.name].is_team_authorization = True + result_providers[provider.identity.name].allow_delete = False + + # get db builtin providers + db_builtin_providers: List[BuiltinToolProvider] = db.session.query(BuiltinToolProvider). \ + filter(BuiltinToolProvider.tenant_id == tenant_id).all() + + for db_builtin_provider in db_builtin_providers: + # add provider into providers + credentails = db_builtin_provider.credentials + provider_name = db_builtin_provider.provider + result_providers[provider_name].is_team_authorization = True + + # package builtin tool provider controller + controller = ToolManager.get_builtin_provider(provider_name) + + # init tool configuration + tool_configuration = ToolConfiguration(tenant_id=tenant_id, provider_controller=controller) + # decrypt the credentials and mask the credentials + decrypted_credentails = tool_configuration.decrypt_tool_credentials(credentials=credentails) + masked_credentials = tool_configuration.mask_tool_credentials(credentials=decrypted_credentails) + + result_providers[provider_name].team_credentials = masked_credentials + + # get db api providers + db_api_providers: List[ApiToolProvider] = db.session.query(ApiToolProvider). \ + filter(ApiToolProvider.tenant_id == tenant_id).all() + + for db_api_provider in db_api_providers: + username = 'Anonymous' + try: + username = db_api_provider.user.name + except Exception as e: + logger.error(f'failed to get user name for api provider {db_api_provider.id}: {str(e)}') + # add provider into providers + credentails = db_api_provider.credentials + provider_name = db_api_provider.name + result_providers[provider_name] = UserToolProvider( + id=db_api_provider.id, + author=username, + name=db_api_provider.name, + description=I18nObject( + en_US=db_api_provider.description, + zh_Hans=db_api_provider.description, + ), + icon=db_api_provider.icon, + label=I18nObject( + en_US=db_api_provider.name, + zh_Hans=db_api_provider.name, + ), + type=UserToolProvider.ProviderType.API, + team_credentials={}, + is_team_authorization=True, + ) + + # package tool provider controller + controller = ApiBasedToolProviderController.from_db( + db_provider=db_api_provider, + auth_type=ApiProviderAuthType.API_KEY if db_api_provider.credentials['auth_type'] == 'api_key' else ApiProviderAuthType.NONE + ) + + # init tool configuration + tool_configuration = ToolConfiguration(tenant_id=tenant_id, provider_controller=controller) + + # decrypt the credentials and mask the credentials + decrypted_credentails = tool_configuration.decrypt_tool_credentials(credentials=credentails) + masked_credentials = tool_configuration.mask_tool_credentials(credentials=decrypted_credentails) + + result_providers[provider_name].team_credentials = masked_credentials + + return BuiltinToolProviderSort.sort(list(result_providers.values())) + + @staticmethod + def get_api_provider_controller(tanent_id: str, provider_id: str) -> Tuple[ApiBasedToolProviderController, Dict[str, Any]]: + """ + get the api provider + + :param provider_name: the name of the provider + + :return: the provider controller, the credentials + """ + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.id == provider_id, + ApiToolProvider.tenant_id == tanent_id, + ).first() + + if provider is None: + raise ToolProviderNotFoundError(f'api provider {provider_id} not found') + + controller = ApiBasedToolProviderController.from_db( + provider, ApiProviderAuthType.API_KEY if provider.credentials['auth_type'] == 'api_key' else ApiProviderAuthType.NONE + ) + controller.load_bundled_tools(provider.tools) + + return controller, provider.credentials + + @staticmethod + def user_get_api_provider(provider: str, tenant_id: str) -> dict: + """ + get api provider + """ + """ + get tool provider + """ + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.tenant_id == tenant_id, + ApiToolProvider.name == provider, + ).first() + + if provider is None: + raise ValueError(f'yout have not added provider {provider}') + + try: + credentials = json.loads(provider.credentials_str) or {} + except: + credentials = {} + + # package tool provider controller + controller = ApiBasedToolProviderController.from_db( + provider, ApiProviderAuthType.API_KEY if credentials['auth_type'] == 'api_key' else ApiProviderAuthType.NONE + ) + # init tool configuration + tool_configuration = ToolConfiguration(tenant_id=tenant_id, provider_controller=controller) + + decrypted_credentails = tool_configuration.decrypt_tool_credentials(credentials) + masked_credentials = tool_configuration.mask_tool_credentials(decrypted_credentails) + + try: + icon = json.loads(provider.icon) + except: + icon = { + "background": "#252525", + "content": "\ud83d\ude01" + } + + return json.loads(serialize_base_model_dict({ + 'schema_type': provider.schema_type, + 'schema': provider.schema, + 'tools': provider.tools, + 'icon': icon, + 'description': provider.description, + 'credentials': masked_credentials, + 'privacy_policy': provider.privacy_policy + })) \ No newline at end of file diff --git a/api/core/tools/utils/configration.py b/api/core/tools/utils/configration.py new file mode 100644 index 000000000..a0ff8d754 --- /dev/null +++ b/api/core/tools/utils/configration.py @@ -0,0 +1,77 @@ +from typing import Dict, Any +from pydantic import BaseModel + +from core.tools.entities.tool_entities import ToolProviderCredentials +from core.tools.provider.tool_provider import ToolProviderController +from core.helper import encrypter + +class ToolConfiguration(BaseModel): + tenant_id: str + provider_controller: ToolProviderController + + def _deep_copy(self, credentails: Dict[str, str]) -> Dict[str, str]: + """ + deep copy credentials + """ + return {key: value for key, value in credentails.items()} + + def encrypt_tool_credentials(self, credentails: Dict[str, str]) -> Dict[str, str]: + """ + encrypt tool credentials with tanent id + + return a deep copy of credentials with encrypted values + """ + credentials = self._deep_copy(credentails) + + # get fields need to be decrypted + fields = self.provider_controller.get_credentails_schema() + for field_name, field in fields.items(): + if field.type == ToolProviderCredentials.CredentialsType.SECRET_INPUT: + if field_name in credentials: + encrypted = encrypter.encrypt_token(self.tenant_id, credentials[field_name]) + credentials[field_name] = encrypted + + return credentials + + def mask_tool_credentials(self, credentials: Dict[str, Any]) -> Dict[str, Any]: + """ + mask tool credentials + + return a deep copy of credentials with masked values + """ + credentials = self._deep_copy(credentials) + + # get fields need to be decrypted + fields = self.provider_controller.get_credentails_schema() + for field_name, field in fields.items(): + if field.type == ToolProviderCredentials.CredentialsType.SECRET_INPUT: + if field_name in credentials: + if len(credentials[field_name]) > 6: + credentials[field_name] = \ + credentials[field_name][:2] + \ + '*' * (len(credentials[field_name]) - 4) +\ + credentials[field_name][-2:] + else: + credentials[field_name] = '*' * len(credentials[field_name]) + + return credentials + + def decrypt_tool_credentials(self, credentials: Dict[str, str]) -> Dict[str, str]: + """ + decrypt tool credentials with tanent id + + return a deep copy of credentials with decrypted values + """ + credentials = self._deep_copy(credentials) + + # get fields need to be decrypted + fields = self.provider_controller.get_credentails_schema() + for field_name, field in fields.items(): + if field.type == ToolProviderCredentials.CredentialsType.SECRET_INPUT: + if field_name in credentials: + try: + credentials[field_name] = encrypter.decrypt_token(self.tenant_id, credentials[field_name]) + except: + pass + + return credentials \ No newline at end of file diff --git a/api/core/tools/utils/encoder.py b/api/core/tools/utils/encoder.py new file mode 100644 index 000000000..eaf9b6bed --- /dev/null +++ b/api/core/tools/utils/encoder.py @@ -0,0 +1,21 @@ +from pydantic import BaseModel +from enum import Enum +from typing import List + +def serialize_base_model_array(l: List[BaseModel]) -> str: + class _BaseModel(BaseModel): + __root__: List[BaseModel] + + """ + {"__root__": [BaseModel, BaseModel, ...]} + """ + return _BaseModel(__root__=l).json() + +def serialize_base_model_dict(b: dict) -> str: + class _BaseModel(BaseModel): + __root__: dict + + """ + {"__root__": {BaseModel}} + """ + return _BaseModel(__root__=b).json() diff --git a/api/core/tools/utils/parser.py b/api/core/tools/utils/parser.py new file mode 100644 index 000000000..f61ac1cbf --- /dev/null +++ b/api/core/tools/utils/parser.py @@ -0,0 +1,341 @@ + +from core.tools.entities.tool_bundle import ApiBasedToolBundle +from core.tools.entities.tool_entities import ToolParamter, ToolParamterOption, ApiProviderSchemaType +from core.tools.entities.common_entities import I18nObject +from core.tools.errors import ToolProviderNotFoundError, ToolNotSupportedError, \ + ToolApiSchemaError + +from typing import List, Tuple + +from yaml import FullLoader, load +from json import loads as json_loads, dumps as json_dumps +from requests import get + +class ApiBasedToolSchemaParser: + @staticmethod + def parse_openapi_to_tool_bundle(openapi: dict, extra_info: dict = None, warning: dict = None) -> List[ApiBasedToolBundle]: + warning = warning if warning is not None else {} + extra_info = extra_info if extra_info is not None else {} + + # set description to extra_info + if 'description' in openapi['info']: + extra_info['description'] = openapi['info']['description'] + else: + extra_info['description'] = '' + + if len(openapi['servers']) == 0: + raise ToolProviderNotFoundError('No server found in the openapi yaml.') + + server_url = openapi['servers'][0]['url'] + + # list all interfaces + interfaces = [] + for path, path_item in openapi['paths'].items(): + methods = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options', 'trace'] + for method in methods: + if method in path_item: + interfaces.append({ + 'path': path, + 'method': method, + 'operation': path_item[method], + }) + + # get all parameters + bundles = [] + for interface in interfaces: + # convert parameters + parameters = [] + if 'parameters' in interface['operation']: + for parameter in interface['operation']['parameters']: + parameters.append(ToolParamter( + name=parameter['name'], + label=I18nObject( + en_US=parameter['name'], + zh_Hans=parameter['name'] + ), + human_description=I18nObject( + en_US=parameter.get('description', ''), + zh_Hans=parameter.get('description', '') + ), + type=ToolParamter.ToolParameterType.STRING, + required=parameter.get('required', False), + form=ToolParamter.ToolParameterForm.LLM, + llm_description=parameter.get('description'), + default=parameter['default'] if 'default' in parameter else None, + )) + # create tool bundle + # check if there is a request body + if 'requestBody' in interface['operation']: + request_body = interface['operation']['requestBody'] + if 'content' in request_body: + for content_type, content in request_body['content'].items(): + # if there is a reference, get the reference and overwrite the content + if 'schema' not in content: + content + + if '$ref' in content['schema']: + # get the reference + root = openapi + reference = content['schema']['$ref'].split('/')[1:] + for ref in reference: + root = root[ref] + # overwrite the content + interface['operation']['requestBody']['content'][content_type]['schema'] = root + # parse body parameters + if 'schema' in interface['operation']['requestBody']['content'][content_type]: + body_schema = interface['operation']['requestBody']['content'][content_type]['schema'] + required = body_schema['required'] if 'required' in body_schema else [] + properties = body_schema['properties'] if 'properties' in body_schema else {} + for name, property in properties.items(): + parameters.append(ToolParamter( + name=name, + label=I18nObject( + en_US=name, + zh_Hans=name + ), + human_description=I18nObject( + en_US=property['description'] if 'description' in property else '', + zh_Hans=property['description'] if 'description' in property else '' + ), + type=ToolParamter.ToolParameterType.STRING, + required=name in required, + form=ToolParamter.ToolParameterForm.LLM, + llm_description=property['description'] if 'description' in property else '', + default=property['default'] if 'default' in property else None, + )) + + # check if parameters is duplicated + parameters_count = {} + for parameter in parameters: + if parameter.name not in parameters_count: + parameters_count[parameter.name] = 0 + parameters_count[parameter.name] += 1 + for name, count in parameters_count.items(): + if count > 1: + warning['duplicated_parameter'] = f'Parameter {name} is duplicated.' + + bundles.append(ApiBasedToolBundle( + server_url=server_url + interface['path'], + method=interface['method'], + summary=interface['operation']['summary'] if 'summary' in interface['operation'] else None, + operation_id=interface['operation']['operationId'], + parameters=parameters, + author='', + icon=None, + openapi=interface['operation'], + )) + + return bundles + + @staticmethod + def parse_openapi_yaml_to_tool_bundle(yaml: str, extra_info: dict = None, warning: dict = None) -> List[ApiBasedToolBundle]: + """ + parse openapi yaml to tool bundle + + :param yaml: the yaml string + :return: the tool bundle + """ + warning = warning if warning is not None else {} + extra_info = extra_info if extra_info is not None else {} + + openapi: dict = load(yaml, Loader=FullLoader) + if openapi is None: + raise ToolApiSchemaError('Invalid openapi yaml.') + return ApiBasedToolSchemaParser.parse_openapi_to_tool_bundle(openapi, extra_info=extra_info, warning=warning) + + @staticmethod + def parse_openapi_json_to_tool_bundle(json: str, extra_info: dict = None, warning: dict = None) -> List[ApiBasedToolBundle]: + """ + parse openapi yaml to tool bundle + + :param yaml: the yaml string + :return: the tool bundle + """ + warning = warning if warning is not None else {} + extra_info = extra_info if extra_info is not None else {} + + openapi: dict = json_loads(json) + if openapi is None: + raise ToolApiSchemaError('Invalid openapi json.') + return ApiBasedToolSchemaParser.parse_openapi_to_tool_bundle(openapi, extra_info=extra_info, warning=warning) + + @staticmethod + def parse_swagger_to_openapi(swagger: dict, extra_info: dict = None, warning: dict = None) -> dict: + """ + parse swagger to openapi + + :param swagger: the swagger dict + :return: the openapi dict + """ + # convert swagger to openapi + info = swagger.get('info', { + 'title': 'Swagger', + 'description': 'Swagger', + 'version': '1.0.0' + }) + + servers = swagger.get('servers', []) + + if len(servers) == 0: + raise ToolApiSchemaError('No server found in the swagger yaml.') + + openapi = { + 'openapi': '3.0.0', + 'info': { + 'title': info.get('title', 'Swagger'), + 'description': info.get('description', 'Swagger'), + 'version': info.get('version', '1.0.0') + }, + 'servers': swagger['servers'], + 'paths': {}, + 'components': { + 'schemas': {} + } + } + + # check paths + if 'paths' not in swagger or len(swagger['paths']) == 0: + raise ToolApiSchemaError('No paths found in the swagger yaml.') + + # convert paths + for path, path_item in swagger['paths'].items(): + openapi['paths'][path] = {} + for method, operation in path_item.items(): + if 'operationId' not in operation: + raise ToolApiSchemaError(f'No operationId found in operation {method} {path}.') + + if 'summary' not in operation or len(operation['summary']) == 0: + warning['missing_summary'] = f'No summary found in operation {method} {path}.' + + if 'description' not in operation or len(operation['description']) == 0: + warning['missing_description'] = f'No description found in operation {method} {path}.' + + openapi['paths'][path][method] = { + 'operationId': operation['operationId'], + 'summary': operation.get('summary', ''), + 'description': operation.get('description', ''), + 'parameters': operation.get('parameters', []), + 'responses': operation.get('responses', {}), + } + + if 'requestBody' in operation: + openapi['paths'][path][method]['requestBody'] = operation['requestBody'] + + # convert definitions + for name, definition in swagger['definitions'].items(): + openapi['components']['schemas'][name] = definition + + return openapi + + @staticmethod + def parse_swagger_yaml_to_tool_bundle(yaml: str, extra_info: dict = None, warning: dict = None) -> List[ApiBasedToolBundle]: + """ + parse swagger yaml to tool bundle + + :param yaml: the yaml string + :return: the tool bundle + """ + warning = warning if warning is not None else {} + extra_info = extra_info if extra_info is not None else {} + + swagger: dict = load(yaml, Loader=FullLoader) + + openapi = ApiBasedToolSchemaParser.parse_swagger_to_openapi(swagger, extra_info=extra_info, warning=warning) + return ApiBasedToolSchemaParser.parse_openapi_to_tool_bundle(openapi, extra_info=extra_info, warning=warning) + + @staticmethod + def parse_swagger_json_to_tool_bundle(json: str, extra_info: dict = None, warning: dict = None) -> List[ApiBasedToolBundle]: + """ + parse swagger yaml to tool bundle + + :param yaml: the yaml string + :return: the tool bundle + """ + warning = warning if warning is not None else {} + extra_info = extra_info if extra_info is not None else {} + + swagger: dict = json_loads(json) + + openapi = ApiBasedToolSchemaParser.parse_swagger_to_openapi(swagger, extra_info=extra_info, warning=warning) + return ApiBasedToolSchemaParser.parse_openapi_to_tool_bundle(openapi, extra_info=extra_info, warning=warning) + + @staticmethod + def parse_openai_plugin_json_to_tool_bundle(json: str, extra_info: dict = None, warning: dict = None) -> List[ApiBasedToolBundle]: + """ + parse openapi plugin yaml to tool bundle + + :param json: the json string + :return: the tool bundle + """ + warning = warning if warning is not None else {} + extra_info = extra_info if extra_info is not None else {} + + try: + openai_plugin = json_loads(json) + api = openai_plugin['api'] + api_url = api['url'] + api_type = api['type'] + except: + raise ToolProviderNotFoundError('Invalid openai plugin json.') + + if api_type != 'openapi': + raise ToolNotSupportedError('Only openapi is supported now.') + + # get openapi yaml + response = get(api_url, headers={ + 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ' + }, timeout=5) + + if response.status_code != 200: + raise ToolProviderNotFoundError('cannot get openapi yaml from url.') + + return ApiBasedToolSchemaParser.parse_openapi_yaml_to_tool_bundle(response.text, extra_info=extra_info, warning=warning) + + @staticmethod + def auto_parse_to_tool_bundle(content: str, extra_info: dict = None, warning: dict = None) -> Tuple[List[ApiBasedToolBundle], str]: + """ + auto parse to tool bundle + + :param content: the content + :return: tools bundle, schema_type + """ + warning = warning if warning is not None else {} + extra_info = extra_info if extra_info is not None else {} + + json_possible = False + content = content.strip() + + if content.startswith('{') and content.endswith('}'): + json_possible = True + + if json_possible: + try: + return ApiBasedToolSchemaParser.parse_openapi_json_to_tool_bundle(content, extra_info=extra_info, warning=warning), \ + ApiProviderSchemaType.OPENAPI.value + except: + pass + + try: + return ApiBasedToolSchemaParser.parse_swagger_json_to_tool_bundle(content, extra_info=extra_info, warning=warning), \ + ApiProviderSchemaType.SWAGGER.value + except: + pass + try: + return ApiBasedToolSchemaParser.parse_openai_plugin_json_to_tool_bundle(content, extra_info=extra_info, warning=warning), \ + ApiProviderSchemaType.OPENAI_PLUGIN.value + except: + pass + else: + try: + return ApiBasedToolSchemaParser.parse_openapi_yaml_to_tool_bundle(content, extra_info=extra_info, warning=warning), \ + ApiProviderSchemaType.OPENAPI.value + except: + pass + + try: + return ApiBasedToolSchemaParser.parse_swagger_yaml_to_tool_bundle(content, extra_info=extra_info, warning=warning), \ + ApiProviderSchemaType.SWAGGER.value + except: + pass + + raise ToolApiSchemaError('Invalid api schema.') \ No newline at end of file diff --git a/api/core/tools/utils/web_reader_tool.py b/api/core/tools/utils/web_reader_tool.py new file mode 100644 index 000000000..b4cfc1987 --- /dev/null +++ b/api/core/tools/utils/web_reader_tool.py @@ -0,0 +1,446 @@ +import hashlib +import json +import os +import re +import site +import subprocess +import tempfile +import unicodedata +from contextlib import contextmanager +from typing import Type, Any + +import requests +from bs4 import BeautifulSoup, NavigableString, Comment, CData +from langchain.chains import RefineDocumentsChain +from langchain.chains.summarize import refine_prompts +from langchain.schema import Document +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain.tools.base import BaseTool +from newspaper import Article +from pydantic import BaseModel, Field +from regex import regex + +from core.chain.llm_chain import LLMChain +from core.data_loader import file_extractor +from core.data_loader.file_extractor import FileExtractor +from core.entities.application_entities import ModelConfigEntity + +FULL_TEMPLATE = """ +TITLE: {title} +AUTHORS: {authors} +PUBLISH DATE: {publish_date} +TOP_IMAGE_URL: {top_image} +TEXT: + +{text} +""" + + +class WebReaderToolInput(BaseModel): + url: str = Field(..., description="URL of the website to read") + summary: bool = Field( + default=False, + description="When the user's question requires extracting the summarizing content of the webpage, " + "set it to true." + ) + cursor: int = Field( + default=0, + description="Start reading from this character." + "Use when the first response was truncated" + "and you want to continue reading the page." + "The value cannot exceed 24000.", + ) + + +class WebReaderTool(BaseTool): + """Reader tool for getting website title and contents. Gives more control than SimpleReaderTool.""" + + name: str = "web_reader" + args_schema: Type[BaseModel] = WebReaderToolInput + description: str = "use this to read a website. " \ + "If you can answer the question based on the information provided, " \ + "there is no need to use." + page_contents: str = None + url: str = None + max_chunk_length: int = 4000 + summary_chunk_tokens: int = 4000 + summary_chunk_overlap: int = 0 + summary_separators: list[str] = ["\n\n", "。", ".", " ", ""] + continue_reading: bool = True + model_config: ModelConfigEntity + model_parameters: dict[str, Any] + + def _run(self, url: str, summary: bool = False, cursor: int = 0) -> str: + try: + if not self.page_contents or self.url != url: + page_contents = get_url(url) + self.page_contents = page_contents + self.url = url + else: + page_contents = self.page_contents + except Exception as e: + return f'Read this website failed, caused by: {str(e)}.' + + if summary: + character_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder( + chunk_size=self.summary_chunk_tokens, + chunk_overlap=self.summary_chunk_overlap, + separators=self.summary_separators + ) + + texts = character_splitter.split_text(page_contents) + docs = [Document(page_content=t) for t in texts] + + if len(docs) == 0 or docs[0].page_content.endswith('TEXT:'): + return "No content found." + + # only use first 5 docs + if len(docs) > 5: + docs = docs[:5] + + chain = self.get_summary_chain() + try: + page_contents = chain.run(docs) + except Exception as e: + return f'Read this website failed, caused by: {str(e)}.' + else: + page_contents = page_result(page_contents, cursor, self.max_chunk_length) + + if self.continue_reading and len(page_contents) >= self.max_chunk_length: + page_contents += f"\nPAGE WAS TRUNCATED. IF YOU FIND INFORMATION THAT CAN ANSWER QUESTION " \ + f"THEN DIRECT ANSWER AND STOP INVOKING web_reader TOOL, OTHERWISE USE " \ + f"CURSOR={cursor+len(page_contents)} TO CONTINUE READING." + + return page_contents + + async def _arun(self, url: str) -> str: + raise NotImplementedError + + def get_summary_chain(self) -> RefineDocumentsChain: + initial_chain = LLMChain( + model_config=self.model_config, + prompt=refine_prompts.PROMPT, + parameters=self.model_parameters + ) + refine_chain = LLMChain( + model_config=self.model_config, + prompt=refine_prompts.REFINE_PROMPT, + parameters=self.model_parameters + ) + return RefineDocumentsChain( + initial_llm_chain=initial_chain, + refine_llm_chain=refine_chain, + document_variable_name="text", + initial_response_name="existing_answer", + callbacks=self.callbacks + ) + + +def page_result(text: str, cursor: int, max_length: int) -> str: + """Page through `text` and return a substring of `max_length` characters starting from `cursor`.""" + return text[cursor: cursor + max_length] + + +def get_url(url: str, user_agent: str = None) -> str: + """Fetch URL and return the contents as a string.""" + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" + } + if user_agent: + headers["User-Agent"] = user_agent + + supported_content_types = file_extractor.SUPPORT_URL_CONTENT_TYPES + ["text/html"] + + head_response = requests.head(url, headers=headers, allow_redirects=True, timeout=(5, 10)) + + if head_response.status_code != 200: + return "URL returned status code {}.".format(head_response.status_code) + + # check content-type + main_content_type = head_response.headers.get('Content-Type').split(';')[0].strip() + if main_content_type not in supported_content_types: + return "Unsupported content-type [{}] of URL.".format(main_content_type) + + if main_content_type in file_extractor.SUPPORT_URL_CONTENT_TYPES: + return FileExtractor.load_from_url(url, return_text=True) + + response = requests.get(url, headers=headers, allow_redirects=True, timeout=(5, 30)) + a = extract_using_readabilipy(response.text) + + if not a['plain_text'] or not a['plain_text'].strip(): + return get_url_from_newspaper3k(url) + + res = FULL_TEMPLATE.format( + title=a['title'], + authors=a['byline'], + publish_date=a['date'], + top_image="", + text=a['plain_text'] if a['plain_text'] else "", + ) + + return res + + +def get_url_from_newspaper3k(url: str) -> str: + + a = Article(url) + a.download() + a.parse() + + res = FULL_TEMPLATE.format( + title=a.title, + authors=a.authors, + publish_date=a.publish_date, + top_image=a.top_image, + text=a.text, + ) + + return res + + +def extract_using_readabilipy(html): + with tempfile.NamedTemporaryFile(delete=False, mode='w+') as f_html: + f_html.write(html) + f_html.close() + html_path = f_html.name + + # Call Mozilla's Readability.js Readability.parse() function via node, writing output to a temporary file + article_json_path = html_path + ".json" + jsdir = os.path.join(find_module_path('readabilipy'), 'javascript') + with chdir(jsdir): + subprocess.check_call(["node", "ExtractArticle.js", "-i", html_path, "-o", article_json_path]) + + # Read output of call to Readability.parse() from JSON file and return as Python dictionary + with open(article_json_path, "r", encoding="utf-8") as json_file: + input_json = json.loads(json_file.read()) + + # Deleting files after processing + os.unlink(article_json_path) + os.unlink(html_path) + + article_json = { + "title": None, + "byline": None, + "date": None, + "content": None, + "plain_content": None, + "plain_text": None + } + # Populate article fields from readability fields where present + if input_json: + if "title" in input_json and input_json["title"]: + article_json["title"] = input_json["title"] + if "byline" in input_json and input_json["byline"]: + article_json["byline"] = input_json["byline"] + if "date" in input_json and input_json["date"]: + article_json["date"] = input_json["date"] + if "content" in input_json and input_json["content"]: + article_json["content"] = input_json["content"] + article_json["plain_content"] = plain_content(article_json["content"], False, False) + article_json["plain_text"] = extract_text_blocks_as_plain_text(article_json["plain_content"]) + if "textContent" in input_json and input_json["textContent"]: + article_json["plain_text"] = input_json["textContent"] + article_json["plain_text"] = re.sub(r'\n\s*\n', '\n', article_json["plain_text"]) + + return article_json + + +def find_module_path(module_name): + for package_path in site.getsitepackages(): + potential_path = os.path.join(package_path, module_name) + if os.path.exists(potential_path): + return potential_path + + return None + +@contextmanager +def chdir(path): + """Change directory in context and return to original on exit""" + # From https://stackoverflow.com/a/37996581, couldn't find a built-in + original_path = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(original_path) + + +def extract_text_blocks_as_plain_text(paragraph_html): + # Load article as DOM + soup = BeautifulSoup(paragraph_html, 'html.parser') + # Select all lists + list_elements = soup.find_all(['ul', 'ol']) + # Prefix text in all list items with "* " and make lists paragraphs + for list_element in list_elements: + plain_items = "".join(list(filter(None, [plain_text_leaf_node(li)["text"] for li in list_element.find_all('li')]))) + list_element.string = plain_items + list_element.name = "p" + # Select all text blocks + text_blocks = [s.parent for s in soup.find_all(string=True)] + text_blocks = [plain_text_leaf_node(block) for block in text_blocks] + # Drop empty paragraphs + text_blocks = list(filter(lambda p: p["text"] is not None, text_blocks)) + return text_blocks + + +def plain_text_leaf_node(element): + # Extract all text, stripped of any child HTML elements and normalise it + plain_text = normalise_text(element.get_text()) + if plain_text != "" and element.name == "li": + plain_text = "* {}, ".format(plain_text) + if plain_text == "": + plain_text = None + if "data-node-index" in element.attrs: + plain = {"node_index": element["data-node-index"], "text": plain_text} + else: + plain = {"text": plain_text} + return plain + + +def plain_content(readability_content, content_digests, node_indexes): + # Load article as DOM + soup = BeautifulSoup(readability_content, 'html.parser') + # Make all elements plain + elements = plain_elements(soup.contents, content_digests, node_indexes) + if node_indexes: + # Add node index attributes to nodes + elements = [add_node_indexes(element) for element in elements] + # Replace article contents with plain elements + soup.contents = elements + return str(soup) + + +def plain_elements(elements, content_digests, node_indexes): + # Get plain content versions of all elements + elements = [plain_element(element, content_digests, node_indexes) + for element in elements] + if content_digests: + # Add content digest attribute to nodes + elements = [add_content_digest(element) for element in elements] + return elements + + +def plain_element(element, content_digests, node_indexes): + # For lists, we make each item plain text + if is_leaf(element): + # For leaf node elements, extract the text content, discarding any HTML tags + # 1. Get element contents as text + plain_text = element.get_text() + # 2. Normalise the extracted text string to a canonical representation + plain_text = normalise_text(plain_text) + # 3. Update element content to be plain text + element.string = plain_text + elif is_text(element): + if is_non_printing(element): + # The simplified HTML may have come from Readability.js so might + # have non-printing text (e.g. Comment or CData). In this case, we + # keep the structure, but ensure that the string is empty. + element = type(element)("") + else: + plain_text = element.string + plain_text = normalise_text(plain_text) + element = type(element)(plain_text) + else: + # If not a leaf node or leaf type call recursively on child nodes, replacing + element.contents = plain_elements(element.contents, content_digests, node_indexes) + return element + + +def add_node_indexes(element, node_index="0"): + # Can't add attributes to string types + if is_text(element): + return element + # Add index to current element + element["data-node-index"] = node_index + # Add index to child elements + for local_idx, child in enumerate( + [c for c in element.contents if not is_text(c)], start=1): + # Can't add attributes to leaf string types + child_index = "{stem}.{local}".format( + stem=node_index, local=local_idx) + add_node_indexes(child, node_index=child_index) + return element + + +def normalise_text(text): + """Normalise unicode and whitespace.""" + # Normalise unicode first to try and standardise whitespace characters as much as possible before normalising them + text = strip_control_characters(text) + text = normalise_unicode(text) + text = normalise_whitespace(text) + return text + + +def strip_control_characters(text): + """Strip out unicode control characters which might break the parsing.""" + # Unicode control characters + # [Cc]: Other, Control [includes new lines] + # [Cf]: Other, Format + # [Cn]: Other, Not Assigned + # [Co]: Other, Private Use + # [Cs]: Other, Surrogate + control_chars = set(['Cc', 'Cf', 'Cn', 'Co', 'Cs']) + retained_chars = ['\t', '\n', '\r', '\f'] + + # Remove non-printing control characters + return "".join(["" if (unicodedata.category(char) in control_chars) and (char not in retained_chars) else char for char in text]) + + +def normalise_unicode(text): + """Normalise unicode such that things that are visually equivalent map to the same unicode string where possible.""" + normal_form = "NFKC" + text = unicodedata.normalize(normal_form, text) + return text + + +def normalise_whitespace(text): + """Replace runs of whitespace characters with a single space as this is what happens when HTML text is displayed.""" + text = regex.sub(r"\s+", " ", text) + # Remove leading and trailing whitespace + text = text.strip() + return text + +def is_leaf(element): + return (element.name in ['p', 'li']) + + +def is_text(element): + return isinstance(element, NavigableString) + + +def is_non_printing(element): + return any(isinstance(element, _e) for _e in [Comment, CData]) + + +def add_content_digest(element): + if not is_text(element): + element["data-content-digest"] = content_digest(element) + return element + + +def content_digest(element): + if is_text(element): + # Hash + trimmed_string = element.string.strip() + if trimmed_string == "": + digest = "" + else: + digest = hashlib.sha256(trimmed_string.encode('utf-8')).hexdigest() + else: + contents = element.contents + num_contents = len(contents) + if num_contents == 0: + # No hash when no child elements exist + digest = "" + elif num_contents == 1: + # If single child, use digest of child + digest = content_digest(contents[0]) + else: + # Build content digest from the "non-empty" digests of child nodes + digest = hashlib.sha256() + child_digests = list( + filter(lambda x: x != "", [content_digest(content) for content in contents])) + for child in child_digests: + digest.update(child.encode('utf-8')) + digest = digest.hexdigest() + return digest diff --git a/api/events/event_handlers/update_app_dataset_join_when_app_model_config_updated.py b/api/events/event_handlers/update_app_dataset_join_when_app_model_config_updated.py index 4f784c664..2b202c53d 100644 --- a/api/events/event_handlers/update_app_dataset_join_when_app_model_config_updated.py +++ b/api/events/event_handlers/update_app_dataset_join_when_app_model_config_updated.py @@ -50,17 +50,24 @@ def get_dataset_ids_from_model_config(app_model_config: AppModelConfig) -> set: return dataset_ids agent_mode = app_model_config.agent_mode_dict - if agent_mode.get('enabled') is False: - return dataset_ids - if not agent_mode.get('tools'): - return dataset_ids - - tools = agent_mode.get('tools') + tools = agent_mode.get('tools', []) or [] for tool in tools: + if len(list(tool.keys())) != 1: + continue + tool_type = list(tool.keys())[0] tool_config = list(tool.values())[0] if tool_type == "dataset": dataset_ids.add(tool_config.get("id")) + # get dataset from dataset_configs + dataset_configs = app_model_config.dataset_configs_dict + datasets = dataset_configs.get('datasets', {}) or {} + for dataset in datasets.get('datasets', []) or []: + keys = list(dataset.keys()) + if len(keys) == 1 and keys[0] == 'dataset': + if dataset['dataset'].get('id'): + dataset_ids.add(dataset['dataset'].get('id')) + return dataset_ids diff --git a/api/fields/app_fields.py b/api/fields/app_fields.py index f303c3786..9030b2fe4 100644 --- a/api/fields/app_fields.py +++ b/api/fields/app_fields.py @@ -40,6 +40,7 @@ app_detail_fields = { 'id': fields.String, 'name': fields.String, 'mode': fields.String, + 'is_agent': fields.Boolean, 'icon': fields.String, 'icon_background': fields.String, 'enable_site': fields.Boolean, @@ -64,6 +65,7 @@ app_partial_fields = { 'id': fields.String, 'name': fields.String, 'mode': fields.String, + 'is_agent': fields.Boolean, 'icon': fields.String, 'icon_background': fields.String, 'enable_site': fields.Boolean, @@ -120,11 +122,13 @@ app_detail_fields_with_site = { 'enable_api': fields.Boolean, 'api_rpm': fields.Integer, 'api_rph': fields.Integer, + 'is_agent': fields.Boolean, 'is_demo': fields.Boolean, 'model_config': fields.Nested(model_config_fields, attribute='app_model_config'), 'site': fields.Nested(site_fields), 'api_base_url': fields.String, - 'created_at': TimestampField + 'created_at': TimestampField, + 'deleted_tools': fields.List(fields.String), } app_site_fields = { diff --git a/api/fields/conversation_fields.py b/api/fields/conversation_fields.py index 5ab73115d..557f047a9 100644 --- a/api/fields/conversation_fields.py +++ b/api/fields/conversation_fields.py @@ -39,6 +39,20 @@ message_file_fields = { 'id': fields.String, 'type': fields.String, 'url': fields.String, + 'belongs_to': fields.String(default='user'), +} + +agent_thought_fields = { + 'id': fields.String, + 'chain_id': fields.String, + 'message_id': fields.String, + 'position': fields.Integer, + 'thought': fields.String, + 'tool': fields.String, + 'tool_input': fields.String, + 'created_at': TimestampField, + 'observation': fields.String, + 'files': fields.List(fields.String) } message_detail_fields = { @@ -58,6 +72,7 @@ message_detail_fields = { 'annotation': fields.Nested(annotation_fields, allow_null=True), 'annotation_hit_history': fields.Nested(annotation_hit_history_fields, allow_null=True), 'created_at': TimestampField, + 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)), 'message_files': fields.List(fields.Nested(message_file_fields), attribute='files'), } diff --git a/api/fields/installed_app_fields.py b/api/fields/installed_app_fields.py index 95b2088c2..f1c2377f4 100644 --- a/api/fields/installed_app_fields.py +++ b/api/fields/installed_app_fields.py @@ -17,6 +17,7 @@ installed_app_fields = { 'last_used_at': TimestampField, 'editable': fields.Boolean, 'uninstallable': fields.Boolean, + 'is_agent': fields.Boolean, } installed_app_list_fields = { diff --git a/api/fields/message_fields.py b/api/fields/message_fields.py index 5995abbcf..397b9795b 100644 --- a/api/fields/message_fields.py +++ b/api/fields/message_fields.py @@ -25,20 +25,57 @@ retriever_resource_fields = { 'created_at': TimestampField } +feedback_fields = { + 'rating': fields.String +} + +agent_thought_fields = { + 'id': fields.String, + 'chain_id': fields.String, + 'message_id': fields.String, + 'position': fields.Integer, + 'thought': fields.String, + 'tool': fields.String, + 'tool_input': fields.String, + 'created_at': TimestampField, + 'observation': fields.String, + 'files': fields.List(fields.String) +} + +retriever_resource_fields = { + 'id': fields.String, + 'message_id': fields.String, + 'position': fields.Integer, + 'dataset_id': fields.String, + 'dataset_name': fields.String, + 'document_id': fields.String, + 'document_name': fields.String, + 'data_source_type': fields.String, + 'segment_id': fields.String, + 'score': fields.Float, + 'hit_count': fields.Integer, + 'word_count': fields.Integer, + 'segment_position': fields.Integer, + 'index_node_hash': fields.String, + 'content': fields.String, + 'created_at': TimestampField +} + message_fields = { 'id': fields.String, 'conversation_id': fields.String, 'inputs': fields.Raw, 'query': fields.String, 'answer': fields.String, - 'message_files': fields.List(fields.Nested(message_file_fields), attribute='files'), 'feedback': fields.Nested(feedback_fields, attribute='user_feedback', allow_null=True), 'retriever_resources': fields.List(fields.Nested(retriever_resource_fields)), - 'created_at': TimestampField + 'created_at': TimestampField, + 'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)), + 'message_files': fields.List(fields.Nested(message_file_fields), attribute='files') } message_infinite_scroll_pagination_fields = { 'limit': fields.Integer, 'has_more': fields.Boolean, 'data': fields.List(fields.Nested(message_fields)) -} \ No newline at end of file +} diff --git a/api/migrations/versions/00bacef91f18_rename_api_provider_description.py b/api/migrations/versions/00bacef91f18_rename_api_provider_description.py new file mode 100644 index 000000000..a498c9046 --- /dev/null +++ b/api/migrations/versions/00bacef91f18_rename_api_provider_description.py @@ -0,0 +1,34 @@ +"""rename api provider description + +Revision ID: 00bacef91f18 +Revises: 8ec536f3c800 +Create Date: 2024-01-07 04:07:34.482983 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '00bacef91f18' +down_revision = '8ec536f3c800' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.add_column(sa.Column('description', sa.Text(), nullable=False)) + batch_op.drop_column('description_str') + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.add_column(sa.Column('description_str', sa.TEXT(), autoincrement=False, nullable=False)) + batch_op.drop_column('description') + + # ### end Alembic commands ### diff --git a/api/migrations/versions/053da0c1d756_add_api_tool_privacy.py b/api/migrations/versions/053da0c1d756_add_api_tool_privacy.py new file mode 100644 index 000000000..8d304ebfb --- /dev/null +++ b/api/migrations/versions/053da0c1d756_add_api_tool_privacy.py @@ -0,0 +1,51 @@ +"""add api tool privacy + +Revision ID: 053da0c1d756 +Revises: 4829e54d2fee +Create Date: 2024-01-12 06:47:21.656262 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '053da0c1d756' +down_revision = '4829e54d2fee' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('tool_conversation_variables', + sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('tenant_id', postgresql.UUID(), nullable=False), + sa.Column('conversation_id', postgresql.UUID(), nullable=False), + sa.Column('variables_str', sa.Text(), nullable=False), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.PrimaryKeyConstraint('id', name='tool_conversation_variables_pkey') + ) + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.add_column(sa.Column('privacy_policy', sa.String(length=255), nullable=True)) + batch_op.alter_column('icon', + existing_type=sa.VARCHAR(length=256), + type_=sa.String(length=255), + existing_nullable=False) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.alter_column('icon', + existing_type=sa.String(length=255), + type_=sa.VARCHAR(length=256), + existing_nullable=False) + batch_op.drop_column('privacy_policy') + + op.drop_table('tool_conversation_variables') + # ### end Alembic commands ### diff --git a/api/migrations/versions/114eed84c228_remove_tool_id_from_model_invoke.py b/api/migrations/versions/114eed84c228_remove_tool_id_from_model_invoke.py new file mode 100644 index 000000000..1b1d77055 --- /dev/null +++ b/api/migrations/versions/114eed84c228_remove_tool_id_from_model_invoke.py @@ -0,0 +1,32 @@ +"""remove tool id from model invoke + +Revision ID: 114eed84c228 +Revises: c71211c8f604 +Create Date: 2024-01-10 04:40:57.257824 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '114eed84c228' +down_revision = 'c71211c8f604' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_model_invokes', schema=None) as batch_op: + batch_op.drop_column('tool_id') + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_model_invokes', schema=None) as batch_op: + batch_op.add_column(sa.Column('tool_id', postgresql.UUID(), autoincrement=False, nullable=False)) + + # ### end Alembic commands ### diff --git a/api/migrations/versions/23db93619b9d_add_message_files_into_agent_thought.py b/api/migrations/versions/23db93619b9d_add_message_files_into_agent_thought.py new file mode 100644 index 000000000..25363ca94 --- /dev/null +++ b/api/migrations/versions/23db93619b9d_add_message_files_into_agent_thought.py @@ -0,0 +1,32 @@ +"""add message files into agent thought + +Revision ID: 23db93619b9d +Revises: 8ae9bc661daa +Create Date: 2024-01-18 08:46:37.302657 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '23db93619b9d' +down_revision = '8ae9bc661daa' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('message_agent_thoughts', schema=None) as batch_op: + batch_op.add_column(sa.Column('message_files', sa.Text(), nullable=True)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('message_agent_thoughts', schema=None) as batch_op: + batch_op.drop_column('message_files') + + # ### end Alembic commands ### diff --git a/api/migrations/versions/3ef9b2b6bee6_add_assistant_app.py b/api/migrations/versions/3ef9b2b6bee6_add_assistant_app.py new file mode 100644 index 000000000..4a4a49799 --- /dev/null +++ b/api/migrations/versions/3ef9b2b6bee6_add_assistant_app.py @@ -0,0 +1,67 @@ +"""add_assistant_app + +Revision ID: 3ef9b2b6bee6 +Revises: 89c7899ca936 +Create Date: 2024-01-05 15:26:25.117551 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '3ef9b2b6bee6' +down_revision = '89c7899ca936' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('tool_api_providers', + sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('name', sa.String(length=40), nullable=False), + sa.Column('schema', sa.Text(), nullable=False), + sa.Column('schema_type_str', sa.String(length=40), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('tenant_id', postgresql.UUID(), nullable=False), + sa.Column('description_str', sa.Text(), nullable=False), + sa.Column('tools_str', sa.Text(), nullable=False), + sa.PrimaryKeyConstraint('id', name='tool_api_provider_pkey') + ) + op.create_table('tool_builtin_providers', + sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('tenant_id', postgresql.UUID(), nullable=True), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('provider', sa.String(length=40), nullable=False), + sa.Column('encrypted_credentials', sa.Text(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.PrimaryKeyConstraint('id', name='tool_builtin_provider_pkey'), + sa.UniqueConstraint('tenant_id', 'provider', name='unique_builtin_tool_provider') + ) + op.create_table('tool_published_apps', + sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('app_id', postgresql.UUID(), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('description', sa.Text(), nullable=False), + sa.Column('llm_description', sa.Text(), nullable=False), + sa.Column('query_description', sa.Text(), nullable=False), + sa.Column('query_name', sa.String(length=40), nullable=False), + sa.Column('tool_name', sa.String(length=40), nullable=False), + sa.Column('author', sa.String(length=40), nullable=False), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.ForeignKeyConstraint(['app_id'], ['apps.id'], ), + sa.PrimaryKeyConstraint('id', name='published_app_tool_pkey'), + sa.UniqueConstraint('app_id', 'user_id', name='unique_published_app_tool') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('tool_published_apps') + op.drop_table('tool_builtin_providers') + op.drop_table('tool_api_providers') + # ### end Alembic commands ### diff --git a/api/migrations/versions/4823da1d26cf_add_tool_file.py b/api/migrations/versions/4823da1d26cf_add_tool_file.py new file mode 100644 index 000000000..797a9539b --- /dev/null +++ b/api/migrations/versions/4823da1d26cf_add_tool_file.py @@ -0,0 +1,37 @@ +"""add tool file + +Revision ID: 4823da1d26cf +Revises: 053da0c1d756 +Create Date: 2024-01-15 11:37:16.782718 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '4823da1d26cf' +down_revision = '053da0c1d756' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('tool_files', + sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('tenant_id', postgresql.UUID(), nullable=False), + sa.Column('conversation_id', postgresql.UUID(), nullable=False), + sa.Column('file_key', sa.String(length=255), nullable=False), + sa.Column('mimetype', sa.String(length=255), nullable=False), + sa.Column('original_url', sa.String(length=255), nullable=True), + sa.PrimaryKeyConstraint('id', name='tool_file_pkey') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('tool_files') + # ### end Alembic commands ### diff --git a/api/migrations/versions/4829e54d2fee_change_message_chain_id_to_nullable.py b/api/migrations/versions/4829e54d2fee_change_message_chain_id_to_nullable.py new file mode 100644 index 000000000..f67a18cb2 --- /dev/null +++ b/api/migrations/versions/4829e54d2fee_change_message_chain_id_to_nullable.py @@ -0,0 +1,36 @@ +"""change message chain id to nullable + +Revision ID: 4829e54d2fee +Revises: 114eed84c228 +Create Date: 2024-01-12 03:42:27.362415 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '4829e54d2fee' +down_revision = '114eed84c228' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('message_agent_thoughts', schema=None) as batch_op: + batch_op.alter_column('message_chain_id', + existing_type=postgresql.UUID(), + nullable=True) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('message_agent_thoughts', schema=None) as batch_op: + batch_op.alter_column('message_chain_id', + existing_type=postgresql.UUID(), + nullable=False) + + # ### end Alembic commands ### diff --git a/api/migrations/versions/8ae9bc661daa_add_tool_conversation_variables_idx.py b/api/migrations/versions/8ae9bc661daa_add_tool_conversation_variables_idx.py new file mode 100644 index 000000000..c65372419 --- /dev/null +++ b/api/migrations/versions/8ae9bc661daa_add_tool_conversation_variables_idx.py @@ -0,0 +1,34 @@ +"""add tool conversation variables idx + +Revision ID: 8ae9bc661daa +Revises: 9fafbd60eca1 +Create Date: 2024-01-15 14:22:03.597692 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '8ae9bc661daa' +down_revision = '9fafbd60eca1' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_conversation_variables', schema=None) as batch_op: + batch_op.create_index('conversation_id_idx', ['conversation_id'], unique=False) + batch_op.create_index('user_id_idx', ['user_id'], unique=False) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_conversation_variables', schema=None) as batch_op: + batch_op.drop_index('user_id_idx') + batch_op.drop_index('conversation_id_idx') + + # ### end Alembic commands ### diff --git a/api/migrations/versions/8ec536f3c800_rename_api_provider_credentails.py b/api/migrations/versions/8ec536f3c800_rename_api_provider_credentails.py new file mode 100644 index 000000000..1380512f3 --- /dev/null +++ b/api/migrations/versions/8ec536f3c800_rename_api_provider_credentails.py @@ -0,0 +1,32 @@ +"""rename api provider credentails + +Revision ID: 8ec536f3c800 +Revises: ad472b61a054 +Create Date: 2024-01-07 03:57:35.257545 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '8ec536f3c800' +down_revision = 'ad472b61a054' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.add_column(sa.Column('credentials_str', sa.Text(), nullable=False)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.drop_column('credentials_str') + + # ### end Alembic commands ### diff --git a/api/migrations/versions/9fafbd60eca1_add_message_file_belongs_to.py b/api/migrations/versions/9fafbd60eca1_add_message_file_belongs_to.py new file mode 100644 index 000000000..367c2e731 --- /dev/null +++ b/api/migrations/versions/9fafbd60eca1_add_message_file_belongs_to.py @@ -0,0 +1,32 @@ +"""add message file belongs to + +Revision ID: 9fafbd60eca1 +Revises: 4823da1d26cf +Create Date: 2024-01-15 13:07:20.340896 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '9fafbd60eca1' +down_revision = '4823da1d26cf' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('message_files', schema=None) as batch_op: + batch_op.add_column(sa.Column('belongs_to', sa.String(length=255), nullable=True)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('message_files', schema=None) as batch_op: + batch_op.drop_column('belongs_to') + + # ### end Alembic commands ### diff --git a/api/migrations/versions/ad472b61a054_add_api_provider_icon.py b/api/migrations/versions/ad472b61a054_add_api_provider_icon.py new file mode 100644 index 000000000..1328326c2 --- /dev/null +++ b/api/migrations/versions/ad472b61a054_add_api_provider_icon.py @@ -0,0 +1,32 @@ +"""add api provider icon + +Revision ID: ad472b61a054 +Revises: 3ef9b2b6bee6 +Create Date: 2024-01-07 02:21:23.114790 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'ad472b61a054' +down_revision = '3ef9b2b6bee6' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.add_column(sa.Column('icon', sa.String(length=256), nullable=False)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.drop_column('icon') + + # ### end Alembic commands ### diff --git a/api/migrations/versions/c71211c8f604_add_tool_invoke_model_log.py b/api/migrations/versions/c71211c8f604_add_tool_invoke_model_log.py new file mode 100644 index 000000000..dc96672b5 --- /dev/null +++ b/api/migrations/versions/c71211c8f604_add_tool_invoke_model_log.py @@ -0,0 +1,49 @@ +"""add tool_invoke_model_log + +Revision ID: c71211c8f604 +Revises: f25003750af4 +Create Date: 2024-01-09 11:42:50.664797 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = 'c71211c8f604' +down_revision = 'f25003750af4' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('tool_model_invokes', + sa.Column('id', postgresql.UUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('user_id', postgresql.UUID(), nullable=False), + sa.Column('tenant_id', postgresql.UUID(), nullable=False), + sa.Column('provider', sa.String(length=40), nullable=False), + sa.Column('tool_type', sa.String(length=40), nullable=False), + sa.Column('tool_name', sa.String(length=40), nullable=False), + sa.Column('tool_id', postgresql.UUID(), nullable=False), + sa.Column('model_parameters', sa.Text(), nullable=False), + sa.Column('prompt_messages', sa.Text(), nullable=False), + sa.Column('model_response', sa.Text(), nullable=False), + sa.Column('prompt_tokens', sa.Integer(), server_default=sa.text('0'), nullable=False), + sa.Column('answer_tokens', sa.Integer(), server_default=sa.text('0'), nullable=False), + sa.Column('answer_unit_price', sa.Numeric(precision=10, scale=4), nullable=False), + sa.Column('answer_price_unit', sa.Numeric(precision=10, scale=7), server_default=sa.text('0.001'), nullable=False), + sa.Column('provider_response_latency', sa.Float(), server_default=sa.text('0'), nullable=False), + sa.Column('total_price', sa.Numeric(precision=10, scale=7), nullable=True), + sa.Column('currency', sa.String(length=255), nullable=False), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.PrimaryKeyConstraint('id', name='tool_model_invoke_pkey') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('tool_model_invokes') + # ### end Alembic commands ### diff --git a/api/migrations/versions/de95f5c77138_migration_serpapi_api_key.py b/api/migrations/versions/de95f5c77138_migration_serpapi_api_key.py new file mode 100644 index 000000000..cbb366285 --- /dev/null +++ b/api/migrations/versions/de95f5c77138_migration_serpapi_api_key.py @@ -0,0 +1,109 @@ +"""migration serpapi_api_key + +Revision ID: de95f5c77138 +Revises: 23db93619b9d +Create Date: 2024-01-21 12:09:04.651394 + +""" +from alembic import op +import sqlalchemy as sa +from json import dumps, loads + + +# revision identifiers, used by Alembic. +revision = 'de95f5c77138' +down_revision = '23db93619b9d' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + """ + 1. select all tool_providers + 2. insert api_key to tool_provider_configs + + tool_providers + - id + - tenant_id + - tool_name + - encrypted_credentials + {"api_key": "$KEY"} + - created_at + - updated_at + + tool_builtin_providers + - id <- tool_providers.id + - tenant_id <- tool_providers.tenant_id + - user_id <- tenant_account_joins.account_id (tenant_account_joins.tenant_id = tool_providers.tenant_id and tenant_account_joins.role = 'owner') + - encrypted_credentials <- tool_providers.encrypted_credentials + {"serpapi_api_key": "$KEY"} + - created_at <- tool_providers.created_at + - updated_at <- tool_providers.updated_at + + """ + # select all tool_providers + tool_providers = op.get_bind().execute( + sa.text( + "SELECT * FROM tool_providers WHERE tool_name = 'serpapi'" + ) + ).fetchall() + + # insert api_key to tool_provider_configs + for tool_provider in tool_providers: + id = tool_provider['id'] + tenant_id = tool_provider['tenant_id'] + encrypted_credentials = tool_provider['encrypted_credentials'] + + try: + credentials = loads(encrypted_credentials) + api_key = credentials['api_key'] + credentials['serpapi_api_key'] = api_key + credentials.pop('api_key') + encrypted_credentials = dumps(credentials) + except Exception as e: + print(e) + continue + + # get user_id + user_id = op.get_bind().execute( + sa.text( + "SELECT account_id FROM tenant_account_joins WHERE tenant_id = :tenant_id AND role = 'owner'" + ), + tenant_id=tenant_id + ).fetchone()['account_id'] + + created_at = tool_provider['created_at'] + updated_at = tool_provider['updated_at'] + + # insert to tool_builtin_providers + # check if exists + exists = op.get_bind().execute( + sa.text( + "SELECT * FROM tool_builtin_providers WHERE tenant_id = :tenant_id AND provider = 'google'" + ), + tenant_id=tenant_id + ).fetchone() + if exists: + continue + + op.get_bind().execute( + sa.text( + "INSERT INTO tool_builtin_providers (id, tenant_id, user_id, provider, encrypted_credentials, created_at, updated_at) VALUES (:id, :tenant_id, :user_id, :provider, :encrypted_credentials, :created_at, :updated_at)" + ), + id=id, + tenant_id=tenant_id, + user_id=user_id, + provider='google', + encrypted_credentials=encrypted_credentials, + created_at=created_at, + updated_at=updated_at + ) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + pass + # ### end Alembic commands ### diff --git a/api/migrations/versions/f25003750af4_add_created_updated_at.py b/api/migrations/versions/f25003750af4_add_created_updated_at.py new file mode 100644 index 000000000..8bdb6a0ff --- /dev/null +++ b/api/migrations/versions/f25003750af4_add_created_updated_at.py @@ -0,0 +1,34 @@ +"""add created/updated at + +Revision ID: f25003750af4 +Revises: 00bacef91f18 +Create Date: 2024-01-07 04:53:24.441861 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'f25003750af4' +down_revision = '00bacef91f18' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.add_column(sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False)) + batch_op.add_column(sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_api_providers', schema=None) as batch_op: + batch_op.drop_column('updated_at') + batch_op.drop_column('created_at') + + # ### end Alembic commands ### diff --git a/api/models/model.py b/api/models/model.py index dab3bc6f8..f317113e8 100644 --- a/api/models/model.py +++ b/api/models/model.py @@ -1,11 +1,13 @@ import json +import uuid from core.file.upload_file_parser import UploadFileParser +from core.file.tool_file_parser import ToolFileParser from extensions.ext_database import db from flask import current_app, request from flask_login import UserMixin from libs.helper import generate_string -from sqlalchemy import Float +from sqlalchemy import Float, text from sqlalchemy.dialects.postgresql import UUID from .account import Account, Tenant @@ -66,7 +68,65 @@ class App(db.Model): def tenant(self): tenant = db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first() return tenant + + @property + def is_agent(self) -> bool: + app_model_config = self.app_model_config + if not app_model_config: + return False + if not app_model_config.agent_mode: + return False + if self.app_model_config.agent_mode_dict.get('enabled', False) \ + and self.app_model_config.agent_mode_dict.get('strategy', '') in ['function_call', 'react']: + return True + return False + + @property + def deleted_tools(self) -> list: + # get agent mode tools + app_model_config = self.app_model_config + if not app_model_config: + return [] + if not app_model_config.agent_mode: + return [] + agent_mode = app_model_config.agent_mode_dict + tools = agent_mode.get('tools', []) + + provider_ids = [] + for tool in tools: + keys = list(tool.keys()) + if len(keys) >= 4: + provider_type = tool.get('provider_type', '') + provider_id = tool.get('provider_id', '') + if provider_type == 'api': + # check if provider id is a uuid string, if not, skip + try: + uuid.UUID(provider_id) + except Exception: + continue + provider_ids.append(provider_id) + + if not provider_ids: + return [] + + api_providers = db.session.execute( + text('SELECT id FROM tool_api_providers WHERE id IN :provider_ids'), + {'provider_ids': tuple(provider_ids)} + ).fetchall() + + deleted_tools = [] + current_api_provider_ids = [str(api_provider.id) for api_provider in api_providers] + + for tool in tools: + keys = list(tool.keys()) + if len(keys) >= 4: + provider_type = tool.get('provider_type', '') + provider_id = tool.get('provider_id', '') + if provider_type == 'api' and provider_id not in current_api_provider_ids: + deleted_tools.append(tool['tool_name']) + + return deleted_tools class AppModelConfig(db.Model): __tablename__ = 'app_model_configs' @@ -168,7 +228,7 @@ class AppModelConfig(db.Model): @property def agent_mode_dict(self) -> dict: - return json.loads(self.agent_mode) if self.agent_mode else {"enabled": False, "strategy": None, "tools": []} + return json.loads(self.agent_mode) if self.agent_mode else {"enabled": False, "strategy": None, "tools": [], "prompt": None} @property def chat_prompt_config_dict(self) -> dict: @@ -337,6 +397,12 @@ class InstalledApp(db.Model): tenant = db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first() return tenant + @property + def is_agent(self) -> bool: + app = self.app + if not app: + return False + return app.is_agent class Conversation(db.Model): __tablename__ = 'conversations' @@ -582,11 +648,22 @@ class Message(db.Model): upload_file=upload_file, force_url=True ) + if message_file.transfer_method == 'tool_file': + # get extension + if '.' in message_file.url: + extension = f'.{message_file.url.split(".")[-1]}' + if len(extension) > 10: + extension = '.bin' + else: + extension = '.bin' + # add sign url + url = ToolFileParser.get_tool_file_manager().sign_file(file_id=message_file.id, extension=extension) files.append({ 'id': message_file.id, 'type': message_file.type, - 'url': url + 'url': url, + 'belongs_to': message_file.belongs_to if message_file.belongs_to else 'user' }) return files @@ -632,12 +709,12 @@ class MessageFile(db.Model): type = db.Column(db.String(255), nullable=False) transfer_method = db.Column(db.String(255), nullable=False) url = db.Column(db.Text, nullable=True) + belongs_to = db.Column(db.String(255), nullable=True) upload_file_id = db.Column(UUID, nullable=True) created_by_role = db.Column(db.String(255), nullable=False) created_by = db.Column(UUID, nullable=False) created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) - class MessageAnnotation(db.Model): __tablename__ = 'message_annotations' __table_args__ = ( @@ -912,7 +989,7 @@ class MessageAgentThought(db.Model): id = db.Column(UUID, nullable=False, server_default=db.text('uuid_generate_v4()')) message_id = db.Column(UUID, nullable=False) - message_chain_id = db.Column(UUID, nullable=False) + message_chain_id = db.Column(UUID, nullable=True) position = db.Column(db.Integer, nullable=False) thought = db.Column(db.Text, nullable=True) tool = db.Column(db.Text, nullable=True) @@ -924,6 +1001,7 @@ class MessageAgentThought(db.Model): message_token = db.Column(db.Integer, nullable=True) message_unit_price = db.Column(db.Numeric, nullable=True) message_price_unit = db.Column(db.Numeric(10, 7), nullable=False, server_default=db.text('0.001')) + message_files = db.Column(db.Text, nullable=True) answer = db.Column(db.Text, nullable=True) answer_token = db.Column(db.Integer, nullable=True) answer_unit_price = db.Column(db.Numeric, nullable=True) @@ -936,6 +1014,12 @@ class MessageAgentThought(db.Model): created_by = db.Column(UUID, nullable=False) created_at = db.Column(db.DateTime, nullable=False, server_default=db.func.current_timestamp()) + @property + def files(self) -> list: + if self.message_files: + return json.loads(self.message_files) + else: + return [] class DatasetRetrieverResource(db.Model): __tablename__ = 'dataset_retriever_resources' diff --git a/api/models/tools.py b/api/models/tools.py new file mode 100644 index 000000000..74da1cd94 --- /dev/null +++ b/api/models/tools.py @@ -0,0 +1,227 @@ +import json +from enum import Enum +from typing import List + +from sqlalchemy.dialects.postgresql import UUID +from sqlalchemy import ForeignKey + +from extensions.ext_database import db + +from core.tools.entities.tool_bundle import ApiBasedToolBundle +from core.tools.entities.common_entities import I18nObject +from core.tools.entities.tool_entities import ApiProviderSchemaType, ToolRuntimeVariablePool + +from models.model import Tenant, Account, App + +class BuiltinToolProvider(db.Model): + """ + This table stores the tool provider information for built-in tools for each tenant. + """ + __tablename__ = 'tool_builtin_providers' + __table_args__ = ( + db.PrimaryKeyConstraint('id', name='tool_builtin_provider_pkey'), + # one tenant can only have one tool provider with the same name + db.UniqueConstraint('tenant_id', 'provider', name='unique_builtin_tool_provider') + ) + + # id of the tool provider + id = db.Column(UUID, server_default=db.text('uuid_generate_v4()')) + # id of the tenant + tenant_id = db.Column(UUID, nullable=True) + # who created this tool provider + user_id = db.Column(UUID, nullable=False) + # name of the tool provider + provider = db.Column(db.String(40), nullable=False) + # credential of the tool provider + encrypted_credentials = db.Column(db.Text, nullable=True) + created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + + @property + def credentials(self) -> dict: + return json.loads(self.encrypted_credentials) + +class PublishedAppTool(db.Model): + """ + The table stores the apps published as a tool for each person. + """ + __tablename__ = 'tool_published_apps' + __table_args__ = ( + db.PrimaryKeyConstraint('id', name='published_app_tool_pkey'), + db.UniqueConstraint('app_id', 'user_id', name='unique_published_app_tool') + ) + + # id of the tool provider + id = db.Column(UUID, server_default=db.text('uuid_generate_v4()')) + # id of the app + app_id = db.Column(UUID, ForeignKey('apps.id'), nullable=False) + # who published this tool + user_id = db.Column(UUID, nullable=False) + # description of the tool, stored in i18n format, for human + description = db.Column(db.Text, nullable=False) + # llm_description of the tool, for LLM + llm_description = db.Column(db.Text, nullable=False) + # query decription, query will be seem as a parameter of the tool, to describe this parameter to llm, we need this field + query_description = db.Column(db.Text, nullable=False) + # query name, the name of the query parameter + query_name = db.Column(db.String(40), nullable=False) + # name of the tool provider + tool_name = db.Column(db.String(40), nullable=False) + # author + author = db.Column(db.String(40), nullable=False) + created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + + @property + def description_i18n(self) -> I18nObject: + return I18nObject(**json.loads(self.description)) + + @property + def app(self) -> App: + return db.session.query(App).filter(App.id == self.app_id).first() + +class ApiToolProvider(db.Model): + """ + The table stores the api providers. + """ + __tablename__ = 'tool_api_providers' + __table_args__ = ( + db.PrimaryKeyConstraint('id', name='tool_api_provider_pkey'), + ) + + id = db.Column(UUID, server_default=db.text('uuid_generate_v4()')) + # name of the api provider + name = db.Column(db.String(40), nullable=False) + # icon + icon = db.Column(db.String(255), nullable=False) + # original schema + schema = db.Column(db.Text, nullable=False) + schema_type_str = db.Column(db.String(40), nullable=False) + # who created this tool + user_id = db.Column(UUID, nullable=False) + # tanent id + tenant_id = db.Column(UUID, nullable=False) + # description of the provider + description = db.Column(db.Text, nullable=False) + # json format tools + tools_str = db.Column(db.Text, nullable=False) + # json format credentials + credentials_str = db.Column(db.Text, nullable=False) + # privacy policy + privacy_policy = db.Column(db.String(255), nullable=True) + + created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + + @property + def schema_type(self) -> ApiProviderSchemaType: + return ApiProviderSchemaType.value_of(self.schema_type_str) + + @property + def tools(self) -> List[ApiBasedToolBundle]: + return [ApiBasedToolBundle(**tool) for tool in json.loads(self.tools_str)] + + @property + def credentials(self) -> dict: + return json.loads(self.credentials_str) + + @property + def is_taned(self) -> bool: + return self.tenant_id is not None + + @property + def user(self) -> Account: + return db.session.query(Account).filter(Account.id == self.user_id).first() + + @property + def tanent(self) -> Tenant: + return db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first() + +class ToolModelInvoke(db.Model): + """ + store the invoke logs from tool invoke + """ + __tablename__ = "tool_model_invokes" + __table_args__ = ( + db.PrimaryKeyConstraint('id', name='tool_model_invoke_pkey'), + ) + + id = db.Column(UUID, server_default=db.text('uuid_generate_v4()')) + # who invoke this tool + user_id = db.Column(UUID, nullable=False) + # tanent id + tenant_id = db.Column(UUID, nullable=False) + # provider + provider = db.Column(db.String(40), nullable=False) + # type + tool_type = db.Column(db.String(40), nullable=False) + # tool name + tool_name = db.Column(db.String(40), nullable=False) + # invoke parameters + model_parameters = db.Column(db.Text, nullable=False) + # prompt messages + prompt_messages = db.Column(db.Text, nullable=False) + # invoke response + model_response = db.Column(db.Text, nullable=False) + + prompt_tokens = db.Column(db.Integer, nullable=False, server_default=db.text('0')) + answer_tokens = db.Column(db.Integer, nullable=False, server_default=db.text('0')) + answer_unit_price = db.Column(db.Numeric(10, 4), nullable=False) + answer_price_unit = db.Column(db.Numeric(10, 7), nullable=False, server_default=db.text('0.001')) + provider_response_latency = db.Column(db.Float, nullable=False, server_default=db.text('0')) + total_price = db.Column(db.Numeric(10, 7)) + currency = db.Column(db.String(255), nullable=False) + created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + +class ToolConversationVariables(db.Model): + """ + store the conversation variables from tool invoke + """ + __tablename__ = "tool_conversation_variables" + __table_args__ = ( + db.PrimaryKeyConstraint('id', name='tool_conversation_variables_pkey'), + # add index for user_id and conversation_id + db.Index('user_id_idx', 'user_id'), + db.Index('conversation_id_idx', 'conversation_id'), + ) + + id = db.Column(UUID, server_default=db.text('uuid_generate_v4()')) + # conversation user id + user_id = db.Column(UUID, nullable=False) + # tanent id + tenant_id = db.Column(UUID, nullable=False) + # conversation id + conversation_id = db.Column(UUID, nullable=False) + # variables pool + variables_str = db.Column(db.Text, nullable=False) + + created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + + @property + def variables(self) -> dict: + return json.loads(self.variables_str) + +class ToolFile(db.Model): + """ + store the file created by agent + """ + __tablename__ = "tool_files" + __table_args__ = ( + db.PrimaryKeyConstraint('id', name='tool_file_pkey'), + ) + + id = db.Column(UUID, server_default=db.text('uuid_generate_v4()')) + # conversation user id + user_id = db.Column(UUID, nullable=False) + # tanent id + tenant_id = db.Column(UUID, nullable=False) + # conversation id + conversation_id = db.Column(UUID, nullable=False) + # file key + file_key = db.Column(db.String(255), nullable=False) + # mime type + mimetype = db.Column(db.String(255), nullable=False) + # original url + original_url = db.Column(db.String(255), nullable=True) \ No newline at end of file diff --git a/api/requirements.txt b/api/requirements.txt index 9e62f9bd7..639941e39 100644 --- a/api/requirements.txt +++ b/api/requirements.txt @@ -61,4 +61,7 @@ unstructured[docx,pptx,msg,md,ppt]~=0.10.27 bs4~=0.0.1 markdown~=3.5.1 google-generativeai~=0.3.2 -httpx[socks]~=0.24.1 \ No newline at end of file +httpx[socks]~=0.24.1 +pydub~=0.25.1 +matplotlib~=3.8.2 +yfinance~=0.2.35 diff --git a/api/services/app_model_config_service.py b/api/services/app_model_config_service.py index bf7dfab74..f4e697f35 100644 --- a/api/services/app_model_config_service.py +++ b/api/services/app_model_config_service.py @@ -185,7 +185,7 @@ class AppModelConfigService: variables = [] for item in config["user_input_form"]: key = list(item.keys())[0] - if key not in ["text-input", "select", "paragraph"]: + if key not in ["text-input", "select", "paragraph", "external_data_tool"]: raise ValueError("Keys in user_input_form list can only be 'text-input', 'paragraph' or 'select'") form_item = item[key] @@ -262,28 +262,39 @@ class AppModelConfigService: for tool in config["agent_mode"]["tools"]: key = list(tool.keys())[0] - if key not in SUPPORT_TOOLS: - raise ValueError("Keys in agent_mode.tools must be in the specified tool list") + if key in SUPPORT_TOOLS: + # old style, use tool name as key + tool_item = tool[key] - tool_item = tool[key] + if "enabled" not in tool_item or not tool_item["enabled"]: + tool_item["enabled"] = False - if "enabled" not in tool_item or not tool_item["enabled"]: - tool_item["enabled"] = False + if not isinstance(tool_item["enabled"], bool): + raise ValueError("enabled in agent_mode.tools must be of boolean type") - if not isinstance(tool_item["enabled"], bool): - raise ValueError("enabled in agent_mode.tools must be of boolean type") + if key == "dataset": + if 'id' not in tool_item: + raise ValueError("id is required in dataset") - if key == "dataset": - if 'id' not in tool_item: - raise ValueError("id is required in dataset") + try: + uuid.UUID(tool_item["id"]) + except ValueError: + raise ValueError("id in dataset must be of UUID type") - try: - uuid.UUID(tool_item["id"]) - except ValueError: - raise ValueError("id in dataset must be of UUID type") - - if not cls.is_dataset_exists(account, tool_item["id"]): - raise ValueError("Dataset ID does not exist, please check your permission.") + if not cls.is_dataset_exists(account, tool_item["id"]): + raise ValueError("Dataset ID does not exist, please check your permission.") + else: + # latest style, use key-value pair + if "enabled" not in tool or not tool["enabled"]: + tool["enabled"] = False + if "provider_type" not in tool: + raise ValueError("provider_type is required in agent_mode.tools") + if "provider_id" not in tool: + raise ValueError("provider_id is required in agent_mode.tools") + if "tool_name" not in tool: + raise ValueError("tool_name is required in agent_mode.tools") + if "tool_parameters" not in tool: + raise ValueError("tool_parameters is required in agent_mode.tools") # dataset_query_variable cls.is_dataset_query_variable_valid(config, app_mode) @@ -454,6 +465,12 @@ class AppModelConfigService: if 'dataset_configs' not in config or not config["dataset_configs"]: config["dataset_configs"] = {'retrieval_model': 'single'} + if 'datasets' not in config["dataset_configs"] or not config["dataset_configs"]["datasets"]: + config["dataset_configs"]["datasets"] = { + "strategy": "router", + "datasets": [] + } + if not isinstance(config["dataset_configs"], dict): raise ValueError("dataset_configs must be of object type") diff --git a/api/services/completion_service.py b/api/services/completion_service.py index b218839df..6035eb1b5 100644 --- a/api/services/completion_service.py +++ b/api/services/completion_service.py @@ -227,6 +227,8 @@ class CompletionService: input_type = list(config.keys())[0] if variable not in user_inputs or not user_inputs[variable]: + if input_type == "external_data_tool": + continue if "required" in input_config and input_config["required"]: raise ValueError(f"{variable} is required in input form") else: diff --git a/api/services/tools_manage_service.py b/api/services/tools_manage_service.py new file mode 100644 index 000000000..ee530b1c1 --- /dev/null +++ b/api/services/tools_manage_service.py @@ -0,0 +1,523 @@ +from typing import List, Tuple + +from flask import current_app + +from core.tools.tool_manager import ToolManager +from core.tools.entities.user_entities import UserToolProvider, UserTool +from core.tools.entities.tool_entities import ApiProviderSchemaType, ApiProviderAuthType, ToolProviderCredentials, \ + ToolCredentialsOption +from core.tools.entities.common_entities import I18nObject +from core.tools.entities.tool_bundle import ApiBasedToolBundle +from core.tools.provider.tool_provider import ToolProviderController +from core.tools.provider.api_tool_provider import ApiBasedToolProviderController +from core.tools.utils.parser import ApiBasedToolSchemaParser +from core.tools.utils.encoder import serialize_base_model_array, serialize_base_model_dict +from core.tools.utils.configration import ToolConfiguration +from core.tools.errors import ToolProviderCredentialValidationError, ToolProviderNotFoundError, ToolNotFoundError + +from extensions.ext_database import db +from models.tools import BuiltinToolProvider, ApiToolProvider + +from httpx import get + +import json + +class ToolManageService: + @staticmethod + def list_tool_providers(user_id: str, tanent_id: str): + """ + list tool providers + + :return: the list of tool providers + """ + result = [provider.to_dict() for provider in ToolManager.user_list_providers( + user_id, tanent_id + )] + + # add icon url prefix + for provider in result: + ToolManageService.repacket_provider(provider) + + return result + + @staticmethod + def repacket_provider(provider: dict): + """ + repacket provider + + :param provider: the provider dict + """ + url_prefix = (current_app.config.get("CONSOLE_API_URL") + + f"/console/api/workspaces/current/tool-provider/builtin/") + + if 'icon' in provider: + if provider['type'] == UserToolProvider.ProviderType.BUILTIN.value: + provider['icon'] = url_prefix + provider['name'] + '/icon' + elif provider['type'] == UserToolProvider.ProviderType.API.value: + try: + provider['icon'] = json.loads(provider['icon']) + except: + provider['icon'] = { + "background": "#252525", + "content": "\ud83d\ude01" + } + + @staticmethod + def list_builtin_tool_provider_tools( + user_id: str, tenant_id: str, provider: str + ): + """ + list builtin tool provider tools + """ + provider_controller: ToolProviderController = ToolManager.get_builtin_provider(provider) + tools = provider_controller.get_tools() + + result = [ + UserTool( + author=tool.identity.author, + name=tool.identity.name, + label=tool.identity.label, + description=tool.description.human, + parameters=tool.parameters or [] + ) for tool in tools + ] + + return json.loads( + serialize_base_model_array(result) + ) + + @staticmethod + def list_builtin_provider_credentials_schema( + provider_name + ): + """ + list builtin provider credentials schema + + :return: the list of tool providers + """ + provider = ToolManager.get_builtin_provider(provider_name) + return [ + v.to_dict() for _, v in (provider.credentials_schema or {}).items() + ] + + @staticmethod + def parser_api_schema(schema: str) -> List[ApiBasedToolBundle]: + """ + parse api schema to tool bundle + """ + try: + warnings = {} + try: + tool_bundles, schema_type = ApiBasedToolSchemaParser.auto_parse_to_tool_bundle(schema, warning=warnings) + except Exception as e: + raise ValueError(f'invalid schema: {str(e)}') + + credentails_schema = [ + ToolProviderCredentials( + name='auth_type', + type=ToolProviderCredentials.CredentialsType.SELECT, + required=True, + default='none', + options=[ + ToolCredentialsOption(value='none', label=I18nObject( + en_US='None', + zh_Hans='无' + )), + ToolCredentialsOption(value='api_key', label=I18nObject( + en_US='Api Key', + zh_Hans='Api Key' + )), + ], + placeholder=I18nObject( + en_US='Select auth type', + zh_Hans='选择认证方式' + ) + ), + ToolProviderCredentials( + name='api_key_header', + type=ToolProviderCredentials.CredentialsType.TEXT_INPUT, + required=False, + placeholder=I18nObject( + en_US='Enter api key header', + zh_Hans='输入 api key header,如:X-API-KEY' + ), + default='api_key', + help=I18nObject( + en_US='HTTP header name for api key', + zh_Hans='HTTP 头部字段名,用于传递 api key' + ) + ), + ToolProviderCredentials( + name='api_key_value', + type=ToolProviderCredentials.CredentialsType.TEXT_INPUT, + required=False, + placeholder=I18nObject( + en_US='Enter api key', + zh_Hans='输入 api key' + ), + default='' + ), + ] + + return json.loads(serialize_base_model_dict( + { + 'schema_type': schema_type, + 'parameters_schema': tool_bundles, + 'credentials_schema': credentails_schema, + 'warning': warnings + } + )) + except Exception as e: + raise ValueError(f'invalid schema: {str(e)}') + + @staticmethod + def convert_schema_to_tool_bundles(schema: str, extra_info: dict = None) -> List[ApiBasedToolBundle]: + """ + convert schema to tool bundles + + :return: the list of tool bundles, description + """ + try: + tool_bundles = ApiBasedToolSchemaParser.auto_parse_to_tool_bundle(schema, extra_info=extra_info) + return tool_bundles + except Exception as e: + raise ValueError(f'invalid schema: {str(e)}') + + @staticmethod + def create_api_tool_provider( + user_id: str, tenant_id: str, provider_name: str, icon: dict, credentials: dict, + schema_type: str, schema: str, privacy_policy: str + ): + """ + create api tool provider + """ + if schema_type not in [member.value for member in ApiProviderSchemaType]: + raise ValueError(f'invalid schema type {schema}') + + # check if the provider exists + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.tenant_id == tenant_id, + ApiToolProvider.name == provider_name, + ).first() + + if provider is not None: + raise ValueError(f'provider {provider_name} already exists') + + # parse openapi to tool bundle + extra_info = {} + # extra info like description will be set here + tool_bundles, schema_type = ToolManageService.convert_schema_to_tool_bundles(schema, extra_info) + + if len(tool_bundles) > 10: + raise ValueError(f'the number of apis should be less than 10') + + # create db provider + db_provider = ApiToolProvider( + tenant_id=tenant_id, + user_id=user_id, + name=provider_name, + icon=json.dumps(icon), + schema=schema, + description=extra_info.get('description', ''), + schema_type_str=schema_type, + tools_str=serialize_base_model_array(tool_bundles), + credentials_str={}, + privacy_policy=privacy_policy + ) + + if 'auth_type' not in credentials: + raise ValueError('auth_type is required') + + # get auth type, none or api key + auth_type = ApiProviderAuthType.value_of(credentials['auth_type']) + + # create provider entity + provider_controller = ApiBasedToolProviderController.from_db(db_provider, auth_type) + # load tools into provider entity + provider_controller.load_bundled_tools(tool_bundles) + + # encrypt credentials + tool_configuration = ToolConfiguration(tenant_id=tenant_id, provider_controller=provider_controller) + encrypted_credentials = tool_configuration.encrypt_tool_credentials(credentials) + db_provider.credentials_str = json.dumps(encrypted_credentials) + + db.session.add(db_provider) + db.session.commit() + + return { 'result': 'success' } + + @staticmethod + def get_api_tool_provider_remote_schema( + user_id: str, tenant_id: str, url: str + ): + """ + get api tool provider remote schema + """ + headers = { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0", + "Accept": "*/*", + } + + try: + response = get(url, headers=headers, timeout=10) + if response.status_code != 200: + raise ValueError(f'Got status code {response.status_code}') + schema = response.text + + # try to parse schema, avoid SSRF attack + ToolManageService.parser_api_schema(schema) + except Exception as e: + raise ValueError(f'invalid schema, please check the url you provided') + + return { + 'schema': schema + } + + @staticmethod + def list_api_tool_provider_tools( + user_id: str, tenant_id: str, provider: str + ): + """ + list api tool provider tools + """ + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.tenant_id == tenant_id, + ApiToolProvider.name == provider, + ).first() + + if provider is None: + raise ValueError(f'yout have not added provider {provider}') + + return json.loads( + serialize_base_model_array([ + UserTool( + author=tool_bundle.author, + name=tool_bundle.operation_id, + label=I18nObject( + en_US=tool_bundle.operation_id, + zh_Hans=tool_bundle.operation_id + ), + description=I18nObject( + en_US=tool_bundle.summary or '', + zh_Hans=tool_bundle.summary or '' + ), + parameters=tool_bundle.parameters + ) for tool_bundle in provider.tools + ]) + ) + + @staticmethod + def update_builtin_tool_provider( + user_id: str, tenant_id: str, provider_name: str, credentials: dict + ): + """ + update builtin tool provider + """ + try: + # get provider + provider_controller = ToolManager.get_builtin_provider(provider_name) + if not provider_controller.need_credentials: + raise ValueError(f'provider {provider_name} does not need credentials') + # validate credentials + provider_controller.validate_credentials(credentials) + # encrypt credentials + tool_configuration = ToolConfiguration(tenant_id=tenant_id, provider_controller=provider_controller) + credentials = tool_configuration.encrypt_tool_credentials(credentials) + except (ToolProviderNotFoundError, ToolNotFoundError, ToolProviderCredentialValidationError) as e: + raise ValueError(str(e)) + + # get if the provider exists + provider: BuiltinToolProvider = db.session.query(BuiltinToolProvider).filter( + BuiltinToolProvider.tenant_id == tenant_id, + BuiltinToolProvider.provider == provider_name, + ).first() + + if provider is None: + # create provider + provider = BuiltinToolProvider( + tenant_id=tenant_id, + user_id=user_id, + provider=provider_name, + encrypted_credentials=json.dumps(credentials), + ) + + db.session.add(provider) + db.session.commit() + + else: + provider.encrypted_credentials = json.dumps(credentials) + + db.session.add(provider) + db.session.commit() + + return { 'result': 'success' } + + @staticmethod + def update_api_tool_provider( + user_id: str, tenant_id: str, provider_name: str, original_provider: str, icon: str, credentials: dict, + schema_type: str, schema: str, privacy_policy: str + ): + """ + update api tool provider + """ + if schema_type not in [member.value for member in ApiProviderSchemaType]: + raise ValueError(f'invalid schema type {schema}') + + # check if the provider exists + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.tenant_id == tenant_id, + ApiToolProvider.name == original_provider, + ).first() + + if provider is None: + raise ValueError(f'api provider {provider_name} does not exists') + + # parse openapi to tool bundle + extra_info = {} + # extra info like description will be set here + tool_bundles, schema_type = ToolManageService.convert_schema_to_tool_bundles(schema, extra_info) + + # update db provider + provider.name = provider_name + provider.icon = icon + provider.schema = schema + provider.description = extra_info.get('description', '') + provider.schema_type_str = ApiProviderSchemaType.OPENAPI.value + provider.tools_str = serialize_base_model_array(tool_bundles) + provider.credentials_str = json.dumps(credentials) + provider.privacy_policy = privacy_policy + + if 'auth_type' not in credentials: + raise ValueError('auth_type is required') + + # get auth type, none or api key + auth_type = ApiProviderAuthType.value_of(credentials['auth_type']) + + # create provider entity + provider_entity = ApiBasedToolProviderController.from_db(provider, auth_type) + # load tools into provider entity + provider_entity.load_bundled_tools(tool_bundles) + + db.session.add(provider) + db.session.commit() + + return { 'result': 'success' } + + @staticmethod + def delete_builtin_tool_provider( + user_id: str, tenant_id: str, provider: str + ): + """ + delete tool provider + """ + provider: BuiltinToolProvider = db.session.query(BuiltinToolProvider).filter( + BuiltinToolProvider.tenant_id == tenant_id, + BuiltinToolProvider.provider == provider, + ).first() + + if provider is None: + raise ValueError(f'yout have not added provider {provider}') + + db.session.delete(provider) + db.session.commit() + + return { 'result': 'success' } + + @staticmethod + def get_builtin_tool_provider_icon( + provider: str + ): + """ + get tool provider icon and it's minetype + """ + icon_path, mime_type = ToolManager.get_builtin_provider_icon(provider) + with open(icon_path, 'rb') as f: + icon_bytes = f.read() + + return icon_bytes, mime_type + + @staticmethod + def delete_api_tool_provider( + user_id: str, tenant_id: str, provider: str + ): + """ + delete tool provider + """ + provider: ApiToolProvider = db.session.query(ApiToolProvider).filter( + ApiToolProvider.tenant_id == tenant_id, + ApiToolProvider.name == provider, + ).first() + + if provider is None: + raise ValueError(f'yout have not added provider {provider}') + + db.session.delete(provider) + db.session.commit() + + return { 'result': 'success' } + + @staticmethod + def get_api_tool_provider( + user_id: str, tenant_id: str, provider: str + ): + """ + get api tool provider + """ + return ToolManager.user_get_api_provider(provider=provider, tenant_id=tenant_id) + + @staticmethod + def test_api_tool_preview( + tenant_id: str, tool_name: str, credentials: dict, parameters: dict, schema_type: str, schema: str + ): + """ + test api tool before adding api tool provider + + 1. parse schema into tool bundle + """ + if schema_type not in [member.value for member in ApiProviderSchemaType]: + raise ValueError(f'invalid schema type {schema_type}') + + if schema_type == ApiProviderSchemaType.OPENAPI.value: + tool_bundles = ApiBasedToolSchemaParser.parse_openapi_yaml_to_tool_bundle(schema) + else: + raise ValueError(f'invalid schema type {schema_type}') + + # get tool bundle + tool_bundle = next(filter(lambda tb: tb.operation_id == tool_name, tool_bundles), None) + if tool_bundle is None: + raise ValueError(f'invalid tool name {tool_name}') + + # create a fake db provider + db_provider = ApiToolProvider( + tenant_id='', user_id='', name='', icon='', + schema=schema, + description='', + schema_type_str=ApiProviderSchemaType.OPENAPI.value, + tools_str=serialize_base_model_array(tool_bundles), + credentials_str=json.dumps(credentials), + ) + + if 'auth_type' not in credentials: + raise ValueError('auth_type is required') + + # get auth type, none or api key + auth_type = ApiProviderAuthType.value_of(credentials['auth_type']) + + # create provider entity + provider_controller = ApiBasedToolProviderController.from_db(db_provider, auth_type) + # load tools into provider entity + provider_controller.load_bundled_tools(tool_bundles) + + try: + provider_controller.validate_credentials_format(credentials) + # get tool + tool = provider_controller.get_tool(tool_name) + tool = tool.fork_tool_runtime(meta={ + 'credentials': credentials, + 'tenant_id': tenant_id, + }) + tool.validate_credentials(credentials, parameters) + except Exception as e: + return { 'error': str(e) } + + return { 'result': 'success' } \ No newline at end of file diff --git a/api/tests/integration_tests/.gitignore b/api/tests/integration_tests/.gitignore new file mode 100644 index 000000000..426667562 --- /dev/null +++ b/api/tests/integration_tests/.gitignore @@ -0,0 +1 @@ +.env.test \ No newline at end of file diff --git a/api/tests/integration_tests/tools/__init__.py b/api/tests/integration_tests/tools/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/tests/integration_tests/tools/__mock_server/openapi_todo.py b/api/tests/integration_tests/tools/__mock_server/openapi_todo.py new file mode 100644 index 000000000..ba14d365c --- /dev/null +++ b/api/tests/integration_tests/tools/__mock_server/openapi_todo.py @@ -0,0 +1,38 @@ +from flask import Flask, request +from flask_restful import Api, Resource + +app = Flask(__name__) +api = Api(app) + +# Mock data +todos_data = { + "global": ["Buy groceries", "Finish project"], + "user1": ["Go for a run", "Read a book"], +} + +class TodosResource(Resource): + def get(self, username): + todos = todos_data.get(username, []) + return {"todos": todos} + + def post(self, username): + data = request.get_json() + new_todo = data.get("todo") + todos_data.setdefault(username, []).append(new_todo) + return {"message": "Todo added successfully"} + + def delete(self, username): + data = request.get_json() + todo_idx = data.get("todo_idx") + todos = todos_data.get(username, []) + + if 0 <= todo_idx < len(todos): + del todos[todo_idx] + return {"message": "Todo deleted successfully"} + + return {"error": "Invalid todo index"}, 400 + +api.add_resource(TodosResource, '/todos/') + +if __name__ == '__main__': + app.run(port=5003, debug=True) diff --git a/api/tests/integration_tests/tools/test_all_provider.py b/api/tests/integration_tests/tools/test_all_provider.py new file mode 100644 index 000000000..83eccb1b1 --- /dev/null +++ b/api/tests/integration_tests/tools/test_all_provider.py @@ -0,0 +1,9 @@ +from core.tools.tool_manager import ToolManager + +def test_tool_providers(): + """ + Test that all tool providers can be loaded + """ + providers = ToolManager.list_builtin_providers() + for provider in providers: + provider.get_tools()