Full Code of aws-samples/dify-aws-tool for AI

main e0a5ec503689 cached
251 files
14.5 MB
550.2k tokens
431 symbols
1 requests
Download .txt
Showing preview only (2,264K chars total). Download the full file or copy to clipboard to get everything.
Repository: aws-samples/dify-aws-tool
Branch: main
Commit: e0a5ec503689
Files: 251
Total size: 14.5 MB

Directory structure:
gitextract_8xwzjunu/

├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── README_JA.md
├── README_ZH.md
├── builtin_tools/
│   └── aws/
│       ├── aws.py
│       ├── aws.yaml
│       └── tools/
│           ├── apply_guardrail.py
│           ├── apply_guardrail.yaml
│           ├── bedrock_retrieve.py
│           ├── bedrock_retrieve.yaml
│           ├── bedrock_retrieve_and_generate.py
│           ├── bedrock_retrieve_and_generate.yaml
│           ├── extract_frame.py
│           ├── extract_frame.yaml
│           ├── lambda_translate_utils.py
│           ├── lambda_translate_utils.yaml
│           ├── lambda_yaml_to_json.py
│           ├── lambda_yaml_to_json.yaml
│           ├── nova_canvas.py
│           ├── nova_canvas.yaml
│           ├── nova_reel.py
│           ├── nova_reel.yaml
│           ├── opensearch_knn_search.py
│           ├── opensearch_knn_search.yaml
│           ├── s3_operator.py
│           ├── s3_operator.yaml
│           ├── sagemaker_audio_to_text.py
│           ├── sagemaker_audio_to_text.yaml
│           ├── sagemaker_chinese_toxicity_detector.py
│           ├── sagemaker_chinese_toxicity_detector.yaml
│           ├── sagemaker_text_rerank.py
│           ├── sagemaker_text_rerank.yaml
│           ├── sagemaker_tts.py
│           ├── sagemaker_tts.yaml
│           ├── transcribe_asr.py
│           └── transcribe_asr.yaml
├── dify.yaml
├── model_provider/
│   └── sagemaker/
│       ├── __init__.py
│       ├── llm/
│       │   ├── __init__.py
│       │   └── llm.py
│       ├── rerank/
│       │   ├── __init__.py
│       │   └── rerank.py
│       ├── sagemaker.py
│       ├── sagemaker.yaml
│       ├── speech2text/
│       │   ├── __init__.py
│       │   └── speech2text.py
│       ├── text_embedding/
│       │   ├── __init__.py
│       │   └── text_embedding.py
│       └── tts/
│           ├── __init__.py
│           └── tts.py
├── notebook/
│   ├── bge-embedding-m3-deploy.ipynb
│   ├── bge-reranker-v2-m3-deploy.ipynb
│   ├── byoc_qwen_rerank_deploy/
│   │   ├── README.md
│   │   ├── app/
│   │   │   ├── inference.py
│   │   │   └── serve
│   │   ├── build_and_push.sh
│   │   ├── deploy_and_test.ipynb
│   │   └── dockerfile
│   ├── cosyvoice/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build_docker.sh
│   │   ├── code/
│   │   │   ├── api_server.py
│   │   │   ├── inference.py
│   │   │   └── serve
│   │   └── cosyvoice_deploy.ipynb
│   ├── cosyvoice_china_region/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build_docker.sh
│   │   ├── code/
│   │   │   ├── api_server.py
│   │   │   ├── inference.py
│   │   │   └── serve
│   │   └── cosyvoice_deploy.ipynb
│   ├── deploy_lambda_yaml_to_json.md
│   ├── funasr-deploy-china-region.ipynb
│   ├── funasr-deploy.ipynb
│   ├── how_to_deploy.md
│   ├── llm_sagemaker_deploy/
│   │   ├── README.md
│   │   ├── app/
│   │   │   └── serve
│   │   ├── build_and_push.sh
│   │   ├── deploy_and_test.ipynb
│   │   ├── deploy_and_test_qwenvl.ipynb
│   │   └── dockerfile
│   ├── llm_sagemaker_deploy_sglang/
│   │   ├── README.md
│   │   ├── app/
│   │   │   └── serve
│   │   ├── build_and_push.sh
│   │   ├── deploy_and_test.ipynb
│   │   └── dockerfile
│   ├── search_img_by_img/
│   │   └── image_search.ipynb
│   └── whisper-deploy-china-region.ipynb
├── plugins/
│   ├── README.md
│   ├── aws_tools/
│   │   ├── .difyignore
│   │   ├── .gitignore
│   │   ├── GUIDE.md
│   │   ├── PRIVACY.md
│   │   ├── README.md
│   │   ├── main.py
│   │   ├── manifest.yaml
│   │   ├── provider/
│   │   │   ├── aws_tools.py
│   │   │   ├── aws_tools.yaml
│   │   │   └── utils.py
│   │   ├── requirements.txt
│   │   └── tools/
│   │       ├── agentcore-browser-session-manager.py
│   │       ├── agentcore-browser-session-manager.yaml
│   │       ├── agentcore-browser-tool.py
│   │       ├── agentcore-browser-tool.yaml
│   │       ├── agentcore_code_interpreter.py
│   │       ├── agentcore_code_interpreter.yaml
│   │       ├── agentcore_memory.py
│   │       ├── agentcore_memory.yaml
│   │       ├── agentcore_memory_search.py
│   │       ├── agentcore_memory_search.yaml
│   │       ├── apply_guardrail.py
│   │       ├── apply_guardrail.yaml
│   │       ├── bedrock_retrieve.py
│   │       ├── bedrock_retrieve.yaml
│   │       ├── bedrock_retrieve_and_generate.py
│   │       ├── bedrock_retrieve_and_generate.yaml
│   │       ├── dynamodb_manager.py
│   │       ├── dynamodb_manager.yaml
│   │       ├── extract_frame.py
│   │       ├── extract_frame.yaml
│   │       ├── lambda_translate_utils.py
│   │       ├── lambda_translate_utils.yaml
│   │       ├── lambda_yaml_to_json.py
│   │       ├── lambda_yaml_to_json.yaml
│   │       ├── nova_canvas.py
│   │       ├── nova_canvas.yaml
│   │       ├── nova_reel.py
│   │       ├── nova_reel.yaml
│   │       ├── opensearch_knn_search.py
│   │       ├── opensearch_knn_search.yaml
│   │       ├── s3_operator.py
│   │       ├── s3_operator.yaml
│   │       ├── sagemaker_chinese_toxicity_detector.py
│   │       ├── sagemaker_chinese_toxicity_detector.yaml
│   │       ├── sagemaker_text_rerank.py
│   │       ├── sagemaker_text_rerank.yaml
│   │       ├── sagemaker_tts.py
│   │       ├── sagemaker_tts.yaml
│   │       ├── transcribe_asr.py
│   │       ├── transcribe_asr.yaml
│   │       ├── translation_evaluator.py
│   │       └── translation_evaluator.yaml
│   ├── aws_tools.difypkg
│   ├── bedrock/
│   │   ├── .difyignore
│   │   ├── GUIDE.md
│   │   ├── PRIVACY.md
│   │   ├── README.md
│   │   ├── main.py
│   │   ├── manifest.yaml
│   │   ├── models/
│   │   │   ├── llm/
│   │   │   │   ├── _position.yaml
│   │   │   │   ├── ai21.yaml
│   │   │   │   ├── amazon-nova.yaml
│   │   │   │   ├── anthropic-claude.yaml
│   │   │   │   ├── cache_config.py
│   │   │   │   ├── cohere.yaml
│   │   │   │   ├── deepseek.yaml
│   │   │   │   ├── llm.py
│   │   │   │   ├── meta-llama.yaml
│   │   │   │   ├── mistral.yaml
│   │   │   │   ├── model_configurations/
│   │   │   │   │   ├── claude-3-5-haiku.yaml
│   │   │   │   │   ├── claude-3-5-sonnet.yaml
│   │   │   │   │   ├── claude-3-7-sonnet.yaml
│   │   │   │   │   ├── claude-3-haiku.yaml
│   │   │   │   │   ├── claude-3-opus.yaml
│   │   │   │   │   ├── claude-3-sonnet.yaml
│   │   │   │   │   ├── claude-4-opus.yaml
│   │   │   │   │   ├── claude-4-sonnet.yaml
│   │   │   │   │   ├── cohere-command-light.yaml
│   │   │   │   │   ├── cohere-command-r.yaml
│   │   │   │   │   ├── cohere-command-rplus.yaml
│   │   │   │   │   ├── cohere-command.yaml
│   │   │   │   │   ├── nova-lite.yaml
│   │   │   │   │   ├── nova-micro.yaml
│   │   │   │   │   └── nova-pro.yaml
│   │   │   │   ├── model_ids.py
│   │   │   │   ├── openai.yaml
│   │   │   │   └── qwen.yaml
│   │   │   ├── rerank/
│   │   │   │   ├── amazon.rerank-v1.yaml
│   │   │   │   ├── cohere.rerank-v3-5.yaml
│   │   │   │   ├── model_ids.py
│   │   │   │   └── rerank.py
│   │   │   └── text_embedding/
│   │   │       ├── amazon.nova-2-multimodal-embeddings-v1.yaml
│   │   │       ├── amazon.titan-embed-text-v1.yaml
│   │   │       ├── amazon.titan-embed-text-v2.yaml
│   │   │       ├── cohere.embed-english-v3.yaml
│   │   │       ├── cohere.embed-multilingual-v3.yaml
│   │   │       ├── model_ids.py
│   │   │       └── text_embedding.py
│   │   ├── provider/
│   │   │   ├── bedrock.py
│   │   │   ├── bedrock.yaml
│   │   │   └── get_bedrock_client.py
│   │   ├── requirements.txt
│   │   └── utils/
│   │       ├── __init__.py
│   │       └── inference_profile.py
│   ├── bedrock.difypkg
│   ├── sagemaker/
│   │   ├── .difyignore
│   │   ├── .gitignore
│   │   ├── GUIDE.md
│   │   ├── PRIVACY.md
│   │   ├── README.md
│   │   ├── main.py
│   │   ├── manifest.yaml
│   │   ├── models/
│   │   │   ├── llm/
│   │   │   │   ├── __init__.py
│   │   │   │   └── llm.py
│   │   │   ├── rerank/
│   │   │   │   ├── __init__.py
│   │   │   │   └── rerank.py
│   │   │   ├── speech2text/
│   │   │   │   ├── __init__.py
│   │   │   │   └── speech2text.py
│   │   │   ├── text_embedding/
│   │   │   │   ├── __init__.py
│   │   │   │   └── text_embedding.py
│   │   │   └── tts/
│   │   │       ├── __init__.py
│   │   │       └── tts.py
│   │   ├── provider/
│   │   │   ├── sagemaker.py
│   │   │   └── sagemaker.yaml
│   │   └── requirements.txt
│   └── sagemaker.difypkg
└── workflow/
    ├── ASR_Transcribe.yml
    ├── AgentCore-Memory-1.yml
    ├── AgentCore-Memory-2.yml
    ├── LLM-Finetuning-Dataflow-dify.yml
    ├── README.md
    ├── Sagemaker-Bge-Rerank.yml
    ├── andrew_translation_agent.yml
    ├── apply_guardrails.yml
    ├── basic_rag_sample.yml
    ├── bedrock_knowledge_retreival+Chatbot .yml
    ├── chat-with-browser.yml
    ├── claude3_code_translation.yml
    ├── claude_code_translation.yml
    ├── code_interpreter_demo.yml
    ├── edu_question_gen.yml
    ├── eks_upgrade_planning/
    │   ├── README.md
    │   ├── README_zh.md
    │   ├── eks_cluster_info.py
    │   ├── eks_upgrade_planning.yml
    │   └── requirements.txt
    ├── generate_image_video.yml
    ├── marketing-copywriting.yml
    ├── mcp_server_integration.yml
    ├── opensearch_img_search.yml
    ├── rag_based_bot_with_tts.yml
    ├── rag_based_chatbot_for_nextcloud.yml
    ├── s3_rag.yml
    ├── sagemaker_rerank_workflow.yml
    ├── simple_kimi.yml
    ├── svg_designer.yml
    └── term_based_translation_workflow.yml

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
**/.DS_Store
**/.ipynb_checkpoints
**/__pycache__
/venv/
.idea
.DS_Store


================================================
FILE: CODE_OF_CONDUCT.md
================================================
## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing Guidelines

Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
documentation, we greatly value feedback and contributions from our community.

Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
information to effectively respond to your bug report or contribution.


## Reporting Bugs/Feature Requests

We welcome you to use the GitHub issue tracker to report bugs or suggest features.

When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:

* A reproducible test case or series of steps
* The version of our code being used
* Any modifications you've made relevant to the bug
* Anything unusual about your environment or deployment


## Contributing via Pull Requests
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:

1. You are working against the latest source on the *main* branch.
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
3. You open an issue to discuss any significant work - we would hate for your time to be wasted.

To send us a pull request, please:

1. Fork the repository.
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
3. Ensure local tests pass.
4. Commit to your fork using clear commit messages.
5. Send us a pull request, answering any default questions in the pull request interface.
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.

GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).


## Finding contributions to work on
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.


## Code of Conduct
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
opensource-codeofconduct@amazon.com with any additional questions or comments.


## Security issue notifications
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.


## Licensing

See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.


================================================
FILE: LICENSE
================================================
MIT No Attribution

Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.



================================================
FILE: README.md
================================================
![cover-v5-optimized](./dify_on_aws.svg)

<p align="center">
  <a href="https://github.com/aws-samples/dify-aws-tool/blob/main/workflow/README.md">Demos</a> ·
  <a href="https://github.com/aws-samples/dify-aws-tool/blob/main/dify.yaml">Deploy Dify With CloudFormation</a> ·
  <a href="https://github.com/aws-samples/solution-for-deploying-dify-on-aws">Deploy Dify on EKS</a> ·
</p>

<p align="center">
  <a href="https://github.com/langgenius/dify">
    <img src="https://img.shields.io/badge/Powered%20by-Bedrock-277E68" alt="Powered by Bedrock">
  </a>
  <a href="https://aws.amazon.com/">
    <img src="https://img.shields.io/badge/Powered%20by-SageMaker-8750F5" alt="Powered by SageMaker">
  </a>
  <a href="https://aws.amazon.com/">
    <img src="https://img.shields.io/badge/Powered%20by-AWS%20Tools-F37D0B" alt="Powered by S3">
  </a>
</p>

<p align="center">
  <a href="./README_ZH.md"><img alt="简体中文版自述文件" src="https://img.shields.io/badge/简体中文-d9d9d9"></a>
  <a href="./README.md"><img alt="README in English" src="https://img.shields.io/badge/English-d9d9d9"></a>
  <a href="./README_JA.md"><img alt="日本語のREADME" src="https://img.shields.io/badge/日本語-d9d9d9"></a>
</p>


## 📋 Introduction

This repository provides the source code for three plugins in [Dify](https://github.com/langgenius/dify): **Bedrock Model Provider**, **SageMaker Model Provider**, and **AWS Tools**, as well as related workflows and demos for reference by Dify users and AWS users.

### ⚙️ Prerequisites

- Dify environment (can be deployed with one click using AWS CloudFormation - [dify.yaml](./dify.yaml))
  For production deployment, please refer to solution example [Dify-on-EKS](https://github.com/aws-samples/solution-for-deploying-dify-on-aws)
- AWS account and AWS experience
- Basic Linux environment experience

## 🧰 Technical Resources

### Workflows ([Demo Page](./workflow/README.md))

| Name | Description | Link | Dependencies | Owner |
|------|-------------|------|-------------|-------|
| Term_based_translate | Translation workflow with term mapping | [DSL](./workflow/term_based_translation_workflow.yml) | Tool(Term mapping) | [ybalbert](ybalbert@amazon.com) |
| Code_translate | Translation workflow between different code types | [DSL](./workflow/claude3_code_translation.yml) | | [binc](binc@amazon.com) |
| Basic_RAG_Sample | Basic RAG workflow example with custom rerank node | [DSL](./workflow/basic_rag_sample.yml) | Tool(Rerank) | [ybalbert](ybalbert@amazon.com) |
| Andrewyng/translation-agent | Recreation of Andrew Ng's translate agent | [DSL](./workflow/andrew_translation_agent.yml) | | [ybalbert](ybalbert@amazon.com) |
| rag_based_bot_with_tts | RAG-based bot with voice response capability | [DSL](./workflow/rag_based_bot_with_tts.yml) | Tool(TTS) | [ybalbert](ybalbert@amazon.com) |
| s3_rag | simple s3-based rag, no vector db needed | [DSL](./workflow/s3_rag.yml) | S3 Operator | [ybalbert](ybalbert@amazon.com) |
| Marketing-copywriter | End-to-end marketing copywriting | [DSL](./workflow/marketing-copywriting.yml) | | [Lyson Ober](https://www.youtube.com/@lysonober) |
| Simple_Kimi | Simple DIY Kimi | [DSL](./workflow/simple_kimi.yml) | | [ybalbert](ybalbert@amazon.com) |
| SVG_Designer | SVG icon designer | [DSL](./workflow/svg_designer.yml) | | [Li Jigang](https://waytoagi.feishu.cn/wiki/TRlTwxCFJis292kNAzEc9D4BnvY) |
| Education_Question_Gen | Education scenario - question generator | [DSL](./workflow/edu_question_gen.yml) | | [chuanxie](chuanxie@amazon.com) |
| Apply_guardrails | Chat workflow with safety guardrails | [DSL](./workflow/apply_guardrails.yml) | | [amyli](amyli@amazon.com) |
| LLM-Finetuning-Dataflow | LLM fine-tuning data synthesis workflow | [DSL](./workflow/LLM-Finetuning-Dataflow-dify) | [finetuning-on-aws](https://github.com/tsaol/finetuning-on-aws/tree/main) | [caoliuh](caoliuh@amazon.com) |
| Image/Video Generation Workflow | Generate images and videos based on Amazon Nova Canvas and Reel | [DSL](./workflow/generate_image_video.yml) | | [alexwuu](alexwuu@amazon.com) |
| EKS Upgrade Planning | Collect EKS cluster information and generate upgrade plan | [DSL](./workflow/eks_upgrade_planning/eks_upgrade_planning.yml) | | [wxyan](wxyan@amazon.com) |
| Amazon S3 powered DMS with chatbot Capabilities| RAG-based bot for nextcloud integration | [DSL](./workflow/rag_based_chatbot_for_nextcloud.yml) | | [tanzhuaz](tanzhuaz@amazon.com) |
| ASR_Transcribe | Transcribe audio to text | [DSL](./workflow/ASR_Transcribe.yml) | | [ybalbert](ybalbert@amazon.com) |
| Image(Text)-2-Image Search | Image2Image & Text2Image Search | [DSL](./workflow/opensearch_img_search.yml) | OpenSearch Knn Retriever | [ybalbert](ybalbert@amazon.com) |
| MCP Server Integration  | MCP Server Integration Demo | [DSL](./workflow/mcp_server_integration.yml) |  | [ybalbert](ybalbert@amazon.com) |
| Chat-With-Browser | Interact with Remote Browser based on AgentCore Browser Tool | [DSL](./workflow/chat-with-browser.yml) | [agentcore-browser-viewer](https://github.com/ybalbert001/agentcore-browser-viewer) | [ybalbert](ybalbert@amazon.com) |
| Manage-Memory-By-yourself | Manage Your memory by yourself based on AgentCore Memory | [DSL1](./workflow/AgentCore-Memory-1.yml)  [DSL2](./workflow/AgentCore-Memory-2.yml) | | [liniyuan](liniyuan@amazon.com) |
| Execute-Code/Command | Execute code and commands in an isolated managed sandbox based on AgentCore Code Interpreter | [DSL](./workflow/code_interpreter_demo.yml) | | [runpeng](runpeng@amazon.com) |

> 💡 For more workflows, check out community websites: [dify101.com](https://dify101.com/), [difyshare.com](https://difyshare.com/), [Awesome-Dify-Workflow](https://github.com/svcvit/Awesome-Dify-Workflow)

### Extension Tools

| Tool Name | Tool Type | Description | Deployment Documentation | Owner |
|-----------|-----------|-------------|--------------------------|-------|
| Rerank | PAAS | Text similarity ranking | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-reranker-v2-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| TTS | PAAS | Text-to-speech synthesis | [Code](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/cosyvoice) | [ybalbert](ybalbert@amazon.com) |
| Bedrock Guardrails | SAAS | Text moderation tool implemented through Amazon Bedrock Guardrail's standalone ApplyGuardrail API | | [amyli](amyli@amazon.com) |
| Term_multilingual_mapping | PAAS | Word segmentation/term mapping | [Repo](https://github.com/ybalbert001/dynamodb-rag/tree/translate) | [ybalbert](ybalbert@amazon.com) |
| Image Translation Tool | PAAS | Translate text in images | Coming | [tangqy](tangqy@amazon.com) |
| Chinese Toxicity Detector | PAAS | Chinese harmful content detection | Coming | [ychchen](ychchen@amazon.com) |
| Transcribe Tool | SAAS | AWS transcribe service tool (ASR) | | [river xie](chuanxie@amazon.com) |
| Bedrock Retriever | PAAS | Amazon Bedrock knowledge base retrieval tool | | [ychchen](ychchen@amazon.com) |
| S3 Operator | SAAS | Read and write S3 bucket content, can return presigned URLs | | [ybalbert](ybalbert@amazon.com) |
| AWS Bedrock Nova Canvas | SAAS | Generate images based on Amazon Nova Canvas | | [alexwuu](alexwuu@amazon.com) |
| AWS Bedrock Nova Reel | SAAS | Generate videos based on Amazon Nova Reel | | [alexwuu](alexwuu@amazon.com) |
| OpenSearch Knn Retriever | PAAS | Retrieve data from OpenSearch using KNN method | [Notebook](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/search_img_by_img) | [ybalbert](ybalbert@amazon.com) |
| Frame Extractor | PAAS | Extract Frame Images from GIF as LLM Input |  | [ybalbert](ybalbert@amazon.com) |
| AgentCore Browser | SAAS | Interact with remote managed browser session | | [wanglx](wanglx@amazon.com) |
| AgentCore Memory | SAAS | Record/Retrieve short-term/long term memory with managed service | | [liniyuan](liniyuan@amazon.com) |
| AgentCore Code Interpreter | SAAS | Execute code and commands in an isolated managed sandbox | | [runpeng](runpeng@amazon.com) |

### Model Providers

| Model Name | Model Type | Deployment Documentation | Owner |
|------------|------------|--------------------------|-------|
| Any open source LLM | SageMaker\LLM | [Model_hub](https://github.com/aws-samples/llm_model_hub) | [ybalbert](ybalbert@amazon.com) |
| Bge-m3-rerank-v2 | SageMaker\Rerank | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-reranker-v2-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| Bge-embedding-m3 | SageMaker\Embedding | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-embedding-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| CosyVoice | SageMaker\TTS | [Code](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/cosyvoice) | [ybalbert](ybalbert@amazon.com) |
| SenseVoice | SageMaker\ASR | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/funasr-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| Whisper-large-v3-turbo | SageMaker\ASR | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/whisper-deploy-china-region.ipynb) | [ybalbert](ybalbert@amazon.com) |

> **📌 Important Note**
>
> Dify's SageMaker LLM Provider can support most open-source models. We recommend using [Model_hub](https://github.com/aws-samples/llm_model_hub) to deploy these models. It's very user-friendly and supports no-code model fine-tuning and deployment. If you don't want to install [Model_hub](https://github.com/aws-samples/llm_model_hub), you can also refer to this [guide](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/llm_sagemaker_deploy) to deploy LLMs to SageMaker using vllm.
>
> If you want to add your Embedding/Rerank/ASR/TTS models to the Dify Sagemaker Model Provider, you should first deploy them in Amazon SageMaker. Please refer to the corresponding [notebooks](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook) for deployment.

## 🔧 Usage Notes

### Getting Help

- Raise issues on the repository's Issues page
- Consult the internal Lark group

![qr](./QR_Lark.png)

### How to Contribute

- Fork this repository and submit a Merge Request
- Update README.md, adding your work (such as workflows or tools) to the appropriate table

## 📚 Additional Materials

### Demo Videos

- [Dify 1.0.0 Release & AWS Plugin Adaptation](https://aws.highspot.com/items/67c2e250ac191e72528d176d?lfrm=rhp.0)
- [How to Use DeepSeek Models on AWS in Dify? Only 5 Minutes](https://mp.weixin.qq.com/s/psY6m9xUNce4QIyksKvapg)
- [Dify and Model Hub Integration for Mainstream Open-Source Models](https://mp.weixin.qq.com/s/t023tUS7QGb9CzFK40YVYw)
- [Dify Native Content Review Extension API Calls Bedrock Guardrail to Build Responsible AI Applications](https://amazon.awsapps.com/workdocs-preview/index.html#/document/1c6e65aa34790cbcbdd74871369ca1b079f2eb5a3d044d614c6cf4f622f56468)
- [Three Steps to Build Kimi Based on the Latest Bedrock C3.5-V2](https://mp.weixin.qq.com/s/_2obKrn849a6jOxML_8Btw)
- [AWS Services as Tools Integrated into Dify](https://mp.weixin.qq.com/s/ZZK4Qh0kcnlZHIdO82nVZA)
- [Dify and SageMaker ASR/TTS Integration](https://mp.weixin.qq.com/s/g2aey251YPk-tekL1uc_nw)
- [How to use bedrock inference profile](https://github.com/user-attachments/assets/938e879a-b7dd-44e5-a096-4c22f67b319b)

### Related Blogs/Documents

- [Using Amazon Bedrock Guardrail via API Extension in Dify to Add Content Review Safety Guardrails to Chat Applications](https://amzn-chn.feishu.cn/docx/PhNbdiDRDoj8vlxIDjAcKBlVncb)
- [Integrating Dify and AWS Services for More Flexible Translation Workflows](https://br5879sdns.feishu.cn/docx/Osehd7t5ZocVocxhtQycBHDCnfb)
- [Using DeepSeek Models on AWS in Dify](https://amzn-chn.feishu.cn/docx/BtLHdxaG5o9xL6xXZcyciZUCn0f)

### Hands-on Labs

- [Rapidly Build GenAI Apps with Dify](https://catalog.us-east-1.prod.workshops.aws/workshops/2c19fcb1-1f1c-4f52-b759-0ca4d2ae2522/zh-CN)
- [Siliconflow+DeepSeek+Dify workshop](https://catalog.us-east-1.prod.workshops.aws/workshops/87e070e2-5621-4c94-9285-529514ec4454/en-US)



================================================
FILE: README_JA.md
================================================
![cover-v5-optimized](./dify_on_aws.svg)

<p align="center">
  <a href="https://github.com/aws-samples/dify-aws-tool/blob/main/workflow/README.md">Demos</a> ·
  <a href="https://github.com/aws-samples/dify-aws-tool/blob/main/dify.yaml">Deploy Dify With CloudFormation</a> ·
  <a href="https://github.com/aws-samples/solution-for-deploying-dify-on-aws">Deploy Dify on EKS</a> ·
</p>

<p align="center">
  <a href="https://github.com/langgenius/dify">
    <img src="https://img.shields.io/badge/Powered%20by-Bedrock-277E68" alt="Powered by Bedrock">
  </a>
  <a href="https://aws.amazon.com/">
    <img src="https://img.shields.io/badge/Powered%20by-SageMaker-8750F5" alt="Powered by SageMaker">
  </a>
  <a href="https://aws.amazon.com/">
    <img src="https://img.shields.io/badge/Powered%20by-AWS%20Tools-F37D0B" alt="Powered by S3">
  </a>
</p>

<p align="center">
  <a href="./README_ZH.md"><img alt="简体中文版自述文件" src="https://img.shields.io/badge/简体中文-d9d9d9"></a>
  <a href="./README.md"><img alt="README in English" src="https://img.shields.io/badge/English-d9d9d9"></a>
  <a href="./README_JA.md"><img alt="日本語のREADME" src="https://img.shields.io/badge/日本語-d9d9d9"></a>
</p>

## 📋 はじめに

このリポジトリでは、Difyの3つのプラグイン:Bedrock Model Provider、SageMaker Model Provider、およびAWS Toolsのソースコード、並びにDifyユーザーとAWSユーザー向けの参考となる関連ワークフローとデモを提供しています。

## ⚙️ 前提条件

- Dify環境(AWS CloudFormationを使用してワンクリックでデプロイ可能 - [dify.yaml](./dify.yaml))
  本番環境へのデプロイについては、ソリューション例 [Dify-on-EKS](https://github.com/aws-samples/solution-for-deploying-dify-on-aws) を参照してください
- AWSアカウントとAWSの使用経験
- 基本的なLinux環境の使用経験

## 🧰 技術リソース

### ワークフロー ([デモページ](./workflow/README.md))

| 名前 | 説明 | リンク | 依存関係 | 担当者 |
|------|------|------|------|------|
| Term_based_translate | 用語マッピングを含む翻訳ワークフロー | [DSL](./workflow/term_based_translation_workflow.yml) | Tool(用語マッピング) | [ybalbert](ybalbert@amazon.com) |
| Code_translate | 異なるコードタイプ間の翻訳ワークフロー | [DSL](./workflow/claude3_code_translation.yml) | | [binc](binc@amazon.com) |
| Basic_RAG_Sample | カスタムリランクノードを含む基本的なRAGワークフロー例 | [DSL](./workflow/basic_rag_sample.yml) | Tool(Rerank) | [ybalbert](ybalbert@amazon.com) |
| Andrewyng/translation-agent | Andrew Ngの翻訳エージェントの再現 | [DSL](./workflow/andrew_translation_agent.yml) | | [ybalbert](ybalbert@amazon.com) |
| rag_based_bot_with_tts | 音声応答機能を持つRAGベースのボット | [DSL](./workflow/rag_based_bot_with_tts.yml) | Tool(TTS) | [ybalbert](ybalbert@amazon.com) |
| s3_rag | シンプルなS3ベースのRAG、ベクターデータベース不要 | [DSL](./workflow/s3_rag.yml) | S3 Operator | [ybalbert](ybalbert@amazon.com) |
| Marketing-copywriter | エンドツーエンドのマーケティングコピーライティング | [DSL](./workflow/marketing-copywriting.yml) | | [Lyson Ober](https://www.youtube.com/@lysonober) |
| Simple_Kimi | シンプルなDIY Kimi | [DSL](./workflow/simple_kimi.yml) | | [ybalbert](ybalbert@amazon.com) |
| SVG_Designer | SVGアイコンデザイナー | [DSL](./workflow/svg_designer.yml) | | [Li Jigang](https://waytoagi.feishu.cn/wiki/TRlTwxCFJis292kNAzEc9D4BnvY) |
| Education_Question_Gen | 教育シナリオ - 問題生成器 | [DSL](./workflow/edu_question_gen.yml) | | [chuanxie](chuanxie@amazon.com) |
| Apply_guardrails | 安全ガードレールを備えたチャットワークフロー | [DSL](./workflow/apply_guardrails.yml) | | [amyli](amyli@amazon.com) |
| LLM-Finetuning-Dataflow | LLMファインチューニングデータ合成ワークフロー | [DSL](./workflow/LLM-Finetuning-Dataflow-dify) | [finetuning-on-aws](https://github.com/tsaol/finetuning-on-aws/tree/main) | [caoliuh](caoliuh@amazon.com) |
| Image/Video Generation Workflow | Amazon Nova CanvasとReelに基づく画像と動画の生成 | [DSL](./workflow/generate_image_video.yml) | | [alexwuu](alexwuu@amazon.com) |
| EKS Upgrade Planning | EKSクラスター情報を収集しアップグレード計画を生成 | [DSL](./workflow/eks_upgrade_planning/eks_upgrade_planning.yml) | | [wxyan](wxyan@amazon.com) |
| Amazon S3 powered DMS with chatbot Capabilities| Nextcloud 統合のための RAG ベースのボット | [DSL](./workflow/rag_based_chatbot_for_nextcloud.yml) | | [tanzhuaz](tanzhuaz@amazon.com) |
| チャットボット機能を備えた Amazon S3 で動作する DMS | Nextcloud 統合のための RAG ベースのボット | DSL(ドメイン固有言語) | | [tanzhuaz](tanzhuaz@amazon.com) |
| ASR_Transcribe | 音声をテキストに変換 | [DSL](./workflow/ASR_Transcribe.yml) | | [ybalbert](ybalbert@amazon.com) |
| Image(Text)-2-Image Search | 画像検索(テキストから画像、画像から画像) | [DSL](./workflow/opensearch_img_search.yml) | OpenSearch Knn Retriever | [ybalbert](ybalbert@amazon.com) |
| MCP サーバー統合 | MCP サーバー統合デモ | [DSL](./workflow/mcp_server_integration.yml) |  | [ybalbert](ybalbert@amazon.com) |
| Chat-With-Browser | AgentCoreブラウザツールとリモートブラウザとの対話 | [DSL](./workflow/chat-with-browser.yml) | [agentcore-browser-viewer](https://github.com/ybalbert001/agentcore-browser-viewer) | [ybalbert](ybalbert@amazon.com) |
| Manage-Memory-By-yourself | AgentCoreメモリに基づいて自分のメモリを管理する | [DSL1](./workflow/AgentCore-Memory-1.yml)  [DSL2](./workflow/AgentCore-Memory-2.yml) | | [liniyuan](liniyuan@amazon.com) |
| Execute-Code/Command | AgentCore Code Interpreter を使用して隔離された管理されたサンドボックス内でコードとコマンドを実行する | [DSL](./workflow/code_interpreter_demo.yml) | | [runpeng](runpeng@amazon.com) |

> 💡 より多くのワークフローについては、コミュニティサイトをご覧ください: [dify101.com](https://dify101.com/)、[difyshare.com](https://difyshare.com/)、[Awesome-Dify-Workflow](https://github.com/svcvit/Awesome-Dify-Workflow)

### 拡張ツール

| ツール名 | ツールタイプ | 説明 | デプロイドキュメント | 担当者 |
|---------|---------|------|---------|-------|
| Rerank | PAAS | テキスト類似性ランキング | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-reranker-v2-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| TTS | PAAS | テキスト音声合成 | [Code](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/cosyvoice) | [ybalbert](ybalbert@amazon.com) |
| Bedrock Guardrails | SAAS | Amazon Bedrock GuardrailのスタンドアロンApplyGuardrail APIを通じて実装されたテキストモデレーションツール | | [amyli](amyli@amazon.com) |
| Term_multilingual_mapping | PAAS | 単語分割/用語マッピング | [Repo](https://github.com/ybalbert001/dynamodb-rag/tree/translate) | [ybalbert](ybalbert@amazon.com) |
| Image Translation Tool | PAAS | 画像内のテキストを翻訳 | Coming | [tangqy](tangqy@amazon.com) |
| Chinese Toxicity Detector | PAAS | 中国語の有害コンテンツ検出 | Coming | [ychchen](ychchen@amazon.com) |
| Transcribe Tool | SAAS | AWS transcribeサービスツール (ASR) | | [river xie](chuanxie@amazon.com) |
| Bedrock Retriever | PAAS | Amazon Bedrockナレッジベース検索ツール | | [ychchen](ychchen@amazon.com) |
| S3 Operator | SAAS | S3バケットのコンテンツの読み書き、署名付きURLの返却が可能 | | [ybalbert](ybalbert@amazon.com) |
| AWS Bedrock Nova Canvas | SAAS | Amazon Nova Canvasに基づく画像生成 | | [alexwuu](alexwuu@amazon.com) |
| AWS Bedrock Nova Reel | SAAS | Amazon Nova Reelに基づく動画生成 | | [alexwuu](alexwuu@amazon.com) |
| OpenSearch Knn Retriever | PAAS | KNN手法を使用してOpenSearchからデータを検索 | [Notebook](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/search_img_by_img) | [ybalbert](ybalbert@amazon.com) |
| Frame Extractor | PAAS | GIF からフレーム画像を抽出して LLM の入力とする |  | [ybalbert](ybalbert@amazon.com) |
| AgentCore Browser | SAAS | リモートホストされたブラウザ環境と対話する | | [wanglx](wanglx@amazon.com) |
| AgentCore Memory | SAAS | AWSが管理するメモリサービスに基づいて、長期・短期記憶を管理する | | [liniyuan](liniyuan@amazon.com) |
| AgentCore Code Interpreter | SAAS | AWSの隔離されたマネージドサンドボックス内でコードとコマンドを実行する | | [runpeng](runpeng@amazon.com) |


### モデルプロバイダー

| モデル名 | モデルタイプ | デプロイドキュメント | 担当者 |
|---------|---------|---------|-------|
| オープンソースLLM全般 | SageMaker\LLM | [Model_hub](https://github.com/aws-samples/llm_model_hub) | [ybalbert](ybalbert@amazon.com) |
| Bge-m3-rerank-v2 | SageMaker\Rerank | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-reranker-v2-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| Bge-embedding-m3 | SageMaker\Embedding | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-embedding-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| CosyVoice | SageMaker\TTS | [Code](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/cosyvoice) | [ybalbert](ybalbert@amazon.com) |
| SenseVoice | SageMaker\ASR | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/funasr-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| Whisper-large-v3-turbo | SageMaker\ASR | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/whisper-deploy-china-region.ipynb) | [ybalbert](ybalbert@amazon.com) |

> **📌 重要な注意事項**
>
> DifyのSageMaker LLM Providerはほとんどのオープンソースモデルをサポートしています。これらのモデルをデプロイするには[Model_hub](https://github.com/aws-samples/llm_model_hub)の使用をお勧めします。非常に使いやすく、コードなしでモデルのファインチューニングとデプロイをサポートしています。[Model_hub](https://github.com/aws-samples/llm_model_hub)をインストールしたくない場合は、[ガイド](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/llm_sagemaker_deploy)を参照して、vllmを使用してLLMをSageMakerにデプロイすることもできます。
>
> Embedding/Rerank/ASR/TTSモデルをDify Sagemaker Model Providerに追加したい場合は、まずAmazon SageMakerにデプロイする必要があります。デプロイについては、対応する[ノートブック](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook)を参照してください。

## 🔧 使用上の注意

### ヘルプの取得

- リポジトリのIssuesページで問題を提起する
- 内部Larkグループに相談する

![qr](./QR_Lark.png)

### 貢献方法

- このリポジトリをフォークし、マージリクエストを提出する
- README.mdを更新し、あなたの成果(ワークフローやツールなど)を適切な表に追加する

## 📚 追加資料

### デモ動画

- [Dify 1.0.0リリース & AWSプラグイン適応](https://aws.highspot.com/items/67c2e250ac191e72528d176d?lfrm=rhp.0)
- [DifyでAWSのDeepSeekモデルを使用する方法(わずか5分)](https://mp.weixin.qq.com/s/psY6m9xUNce4QIyksKvapg)
- [DifyとModel Hubの統合による主流オープンソースモデルの実現](https://mp.weixin.qq.com/s/t023tUS7QGb9CzFK40YVYw)
- [Difyネイティブコンテンツレビュー拡張APIがBedrock Guardrailを呼び出して責任あるAIアプリケーションを構築](https://amazon.awsapps.com/workdocs-preview/index.html#/document/1c6e65aa34790cbcbdd74871369ca1b079f2eb5a3d044d614c6cf4f622f56468)
- [最新のBedrock C3.5-V2に基づくKimiを構築する3つのステップ](https://mp.weixin.qq.com/s/_2obKrn849a6jOxML_8Btw)
- [AWSサービスをDifyに統合するツール](https://mp.weixin.qq.com/s/ZZK4Qh0kcnlZHIdO82nVZA)
- [DifyとSageMaker ASR/TTSの統合](https://mp.weixin.qq.com/s/g2aey251YPk-tekL1uc_nw)
- [DifyでのBedrock Inference profile使用方法](https://github.com/user-attachments/assets/938e879a-b7dd-44e5-a096-4c22f67b319b)

### 関連ブログ/ドキュメント

- [API拡張を通じてDifyでAmazon Bedrock Guardrailを使用し、チャットアプリケーションにコンテンツレビュー安全ガードレールを追加する](https://amzn-chn.feishu.cn/docx/PhNbdiDRDoj8vlxIDjAcKBlVncb)
- [DifyとAWSサービスを統合してより柔軟な翻訳ワークフローを実現](https://br5879sdns.feishu.cn/docx/Osehd7t5ZocVocxhtQycBHDCnfb)
- [DifyでAWSのDeepSeekモデルを使用する](https://amzn-chn.feishu.cn/docx/BtLHdxaG5o9xL6xXZcyciZUCn0f)

### ハンズオンラボ

- [Difyで迅速にGenAIアプリを構築する](https://catalog.us-east-1.prod.workshops.aws/workshops/2c19fcb1-1f1c-4f52-b759-0ca4d2ae2522/zh-CN)
- [Siliconflow+DeepSeek+Dify workshop](https://catalog.us-east-1.prod.workshops.aws/workshops/87e070e2-5621-4c94-9285-529514ec4454/en-US)

================================================
FILE: README_ZH.md
================================================
![cover-v5-optimized](./dify_on_aws.svg)

<p align="center">
  <a href="https://github.com/aws-samples/dify-aws-tool/blob/main/workflow/README.md">Demos</a> ·
  <a href="https://github.com/aws-samples/dify-aws-tool/blob/main/dify.yaml">Deploy Dify With CloudFormation</a> ·
  <a href="https://github.com/aws-samples/solution-for-deploying-dify-on-aws">Deploy Dify on EKS</a> ·
</p>

<p align="center">
  <a href="https://github.com/langgenius/dify">
    <img src="https://img.shields.io/badge/Powered%20by-Bedrock-277E68" alt="Powered by Bedrock">
  </a>
  <a href="https://aws.amazon.com/">
    <img src="https://img.shields.io/badge/Powered%20by-SageMaker-8750F5" alt="Powered by SageMaker">
  </a>
  <a href="https://aws.amazon.com/">
    <img src="https://img.shields.io/badge/Powered%20by-AWS%20Tools-F37D0B" alt="Powered by S3">
  </a>
</p>

<p align="center">
  <a href="./README_ZH.md"><img alt="简体中文版自述文件" src="https://img.shields.io/badge/简体中文-d9d9d9"></a>
  <a href="./README.md"><img alt="README in English" src="https://img.shields.io/badge/English-d9d9d9"></a>
  <a href="./README_JA.md"><img alt="日本語のREADME" src="https://img.shields.io/badge/日本語-d9d9d9"></a>
</p>

## 📋 简介

本仓库提供了 [Dify](https://github.com/langgenius/dify) 中亚马逊云 **Bedrock Model Provider**、**SageMaker Model Provider** 以及 **AWS Tools** 三个插件的源码,以及一些相关的 Workflow 和 Demo,供 Dify 用户和 AWS 用户参考借鉴。

## ⚙️ 前置条件

- Dify 环境 (可以通过 AWS Cloudformation 一键部署社区版 - [dify.yaml](./dify.yaml))
  对于生产环境部署, 请参考解决方案样例 [Dify-on-EKS](https://github.com/aws-samples/solution-for-deploying-dify-on-aws)
- AWS 账户和 AWS 使用经验
- 基本的 Linux 环境使用经验

## 🧰 技术资源

#### 工作流 ([Demo页面](./workflow/README.md))

| 名称 | 描述 | 链接 | 依赖 | 负责人 |
|------|------|------|------|------|
| Term_based_translate | 集成了专词映射的翻译工作流 | [DSL](./workflow/term_based_translation_workflow.yml) | Tool(专词映射) | [ybalbert](ybalbert@amazon.com) |
| Code_translate | 不同代码种类之间的翻译工作流 | [DSL](./workflow/claude3_code_translation.yml) | | [binc](binc@amazon.com) |
| Basic_RAG_Sample | 最基础的RAG工作流示例,包含自定义rerank节点 | [DSL](./workflow/basic_rag_sample.yml) | Tool(Rerank) | [ybalbert](ybalbert@amazon.com) |
| Andrewyng/translation-agent | 复刻吴恩达的tranlsate agent | [DSL](./workflow/andrew_translation_agent.yml) | | [ybalbert](ybalbert@amazon.com) |
| rag_based_bot_with_tts | 基于RAG能语音回答的Bot | [DSL](./workflow/rag_based_bot_with_tts.yml) | Tool(TTS) | [ybalbert](ybalbert@amazon.com) |
| s3_rag | 简易的基于S3的RAG, 无需向量库 | [DSL](./workflow/s3_rag.yml) | S3 Operator | [ybalbert](ybalbert@amazon.com) |
| Marketing-copywriter | 营销文案一条龙 | [DSL](./workflow/marketing-copywriting.yml) | | [Lyson Ober](https://www.youtube.com/@lysonober) |
| Simple_Kimi | 简易自制Kimi | [DSL](./workflow/simple_kimi.yml) | | [ybalbert](ybalbert@amazon.com) |
| SVG_Designer | SVG 图标设计师 | [DSL](./workflow/svg_designer.yml) | | [李继刚](https://waytoagi.feishu.cn/wiki/TRlTwxCFJis292kNAzEc9D4BnvY) |
| Education_Question_Gen | 教育场景 - 试题生成器 | [DSL](./workflow/edu_question_gen.yml) | | [chuanxie](chuanxie@amazon.com) |
| Apply_guardrails | 应用安全防范的聊天工作流 | [DSL](./workflow/apply_guardrails.yml) | | [amyli](amyli@amazon.com) |
| LLM-Finetuning-Dataflow | LLM微调数据合成工作流 | [DSL](./workflow/LLM-Finetuning-Dataflow-dify) | [finetuning-on-aws](https://github.com/tsaol/finetuning-on-aws/tree/main) | [caoliuh](caoliuh@amazon.com) |
| Image/Video Generation Workflow | 基于Amazon Nova Canvas和Reel生成图片和视频 | [DSL](./workflow/generate_image_video.yml) | | [alexwuu](alexwuu@amazon.com) |
| EKS Upgrade Planning | 采集EKS集群信息并生成EKS集群升级计划 | [DSL](./workflow/eks_upgrade_planning/eks_upgrade_planning.yml) | | [wxyan](wxyan@amazon.com) |
| Bedrock based ChatBot for Nextcloud | 基于Amazon S3 + Bedrock Knowledgebase+Nova Pro的智能网盘 | [DSL](./workflow/rag_based_chatbot_for_nextcloud.yml) | | [tanzhuaz](tanzhuaz@amazon.com) |
| ASR_Transcribe | 语音转录文字 | [DSL](./workflow/ASR_Transcribe.yml) | | [ybalbert](ybalbert@amazon.com) |
| Image(Text)-2-Image Search | 文搜图 & 图搜图 | [DSL](./workflow/opensearch_img_search.yml) | OpenSearch Knn Retriever | [ybalbert](ybalbert@amazon.com) |
| MCP Server 集成  | MCP Server 集成演示 | [DSL](./workflow/mcp_server_integration.yml) |  | [ybalbert](ybalbert@amazon.com) |
| Chat-With-Browser | 基于AgentCore Browser Tool与远程浏览器交互 | [DSL](./workflow/chat-with-browser.yml) | [agentcore-browser-viewer](https://github.com/ybalbert001/agentcore-browser-viewer) | [ybalbert](ybalbert@amazon.com) |
| Manage-Memory-By-yourself | 基于 AgentCore memory自行管理您的内存 | [DSL1](./workflow/AgentCore-Memory-1.yml)  [DSL2](./workflow/AgentCore-Memory-2.yml) | | [liniyuan](liniyuan@amazon.com) |
| Execute-Code/Command | 基于AgentCore Code Interpreter 在隔离的受管沙箱中执行代码和命令 | [DSL](./workflow/code_interpreter_demo.yml) | | [runpeng](runpeng@amazon.com) |

> 💡 更多工作流可以关注社区网站:[dify101.com](https://dify101.com/)、[difyshare.com](https://difyshare.com/)、[Awesome-Dify-Workflow](https://github.com/svcvit/Awesome-Dify-Workflow)

#### 扩展工具

| 工具名称 | 工具类型 | 描述 | 部署文档 | 负责人 |
|---------|---------|------|---------|-------|
| Rerank | PAAS | 文本相似性排序 | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-reranker-v2-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| TTS | PAAS | 语音合成 | [Code](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/cosyvoice) | [ybalbert](ybalbert@amazon.com) |
| Bedrock Guardrails | SAAS | 文本审核工具,通过 Amazon Bedrock Guardrail 上提供的独立评估API ApplyGuardrail 来实现 | | [amyli](amyli@amazon.com) |
| Term_multilingual_mapping | PAAS | 切词/获取专词映射 | [Repo](https://github.com/ybalbert001/dynamodb-rag/tree/translate) | [ybalbert](ybalbert@amazon.com) |
| Image Translation Tool | PAAS | 翻译图片上的文字 | Coming | [tangqy](tangqy@amazon.com) |
| Chinese Toxicity Detector | PAAS | 中文有害内容检测 | Coming | [ychchen](ychchen@amazon.com) |
| Transcribe Tool | SAAS | AWS transcribe service tool (ASR) | | [river xie](chuanxie@amazon.com) |
| Bedrock Retriever | PAAS | Amazon Bedrock知识库检索工具 | | [ychchen](ychchen@amazon.com) |
| S3 Operator | SAAS | 读写S3中bucket的内容,可以返回presignURL | | [ybalbert](ybalbert@amazon.com) |
| AWS Bedrock Nova Canvas | SAAS | 基于Amazon Nova Canvas生成图像 | | [alexwuu](alexwuu@amazon.com) |
| AWS Bedrock Nova Reel | SAAS | 基于Amazon Nova Reel生成视频 | | [alexwuu](alexwuu@amazon.com) |
| OpenSearch Knn Retriever | PAAS | 用KNN方法从OpenSearch召回数据 | [Notebook](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/search_img_by_img) | [ybalbert](ybalbert@amazon.com) |
| Frame Extractor | PAAS | 对GIF输入抽帧作为LLM输入 |  | [ybalbert](ybalbert@amazon.com) |
| AgentCore Browser | SAAS | 与远程托管的浏览器环境进行交互 | | [wanglx](wanglx@amazon.com) |
| AgentCore Memory | SAAS | 基于AWS 托管Memory服务,管理长短记忆 | | [liniyuan](liniyuan@amazon.com) |
| AgentCore Code Interpreter | SAAS | 在AWS隔离的托管沙盒中执行代码和命令 | | [runpeng](runpeng@amazon.com) |

#### 模型提供商

| 模型名称 | 模型类型 | 部署文档 | 负责人 |
|---------|---------|---------|-------|
| 任何开源大语言模型 | SageMaker\LLM | [Model_hub](https://github.com/aws-samples/llm_model_hub) | [ybalbert](ybalbert@amazon.com) |
| Bge-m3-rerank-v2 | SageMaker\Rerank | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-reranker-v2-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| Bge-embedding-m3 | SageMaker\Embedding | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/bge-embedding-m3-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| CosyVoice | SageMaker\TTS | [Code](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/cosyvoice) | [ybalbert](ybalbert@amazon.com) |
| SenseVoice | SageMaker\ASR | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/funasr-deploy.ipynb) | [ybalbert](ybalbert@amazon.com) |
| Whisper-large-v3-turbo | SageMaker\ASR | [Notebook](https://github.com/aws-samples/dify-aws-tool/blob/main/notebook/whisper-deploy-china-region.ipynb) | [ybalbert](ybalbert@amazon.com) |

> **📌 重要提示**
>
> Dify的SageMaker LLM Provider 可以支持大多数开源模型。我们建议您使用 [Model_hub](https://github.com/aws-samples/llm_model_hub) 来部署这些模型。它非常简单易用,支持无代码方式进行模型微调和部署。如果您不想安装 [Model_hub](https://github.com/aws-samples/llm_model_hub),也可以参考[指引](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook/llm_sagemaker_deploy)通过vllm的方式部署LLM到SageMaker。
>
> 如果您想将您的 Embedding/Rerank/ASR/TTS 模型添加到Dify Sagemaker Model Provider,您应该首先在 Amazon SageMaker 中自行部署它们。请参见对应的[notebook](https://github.com/aws-samples/dify-aws-tool/tree/main/notebook)去部署。

## 🔧 使用须知

#### 寻求帮助

- 在仓库Issue页面提出问题

- 到内部飞书群咨询

  ![qr](./QR_Lark.png) 

#### 贡献方式

- Fork本仓库,发Merge Request
- 修改README.md,在表格中添加你的工作(如workflow或者Tool)

## 📚 其他材料

#### 演示视频

- [Dify 1.0.0发布 & AWS插件适配](https://aws.highspot.com/items/67c2e250ac191e72528d176d?lfrm=rhp.0)
- [如何在Dify上使用AWS中的DeepSeek模型?仅5分钟](https://mp.weixin.qq.com/s/psY6m9xUNce4QIyksKvapg)
- [Dify与Model Hub集成实现主流开源模型](https://mp.weixin.qq.com/s/t023tUS7QGb9CzFK40YVYw)
- [Dify 原生内容审查扩展API调用 Bedrock Guardrail构建负责任的AI应用](https://amazon.awsapps.com/workdocs-preview/index.html#/document/1c6e65aa34790cbcbdd74871369ca1b079f2eb5a3d044d614c6cf4f622f56468)
- [三步构建基于最新Bedrock C3.5-V2的Kimi](https://mp.weixin.qq.com/s/_2obKrn849a6jOxML_8Btw)
- [AWS服务作为工具集成到Dify](https://mp.weixin.qq.com/s/ZZK4Qh0kcnlZHIdO82nVZA)
- [Dify与SageMaker上的ASR/TTS集成](https://mp.weixin.qq.com/s/g2aey251YPk-tekL1uc_nw)
- [如何在Dify中使用bedrock inference profile](https://github.com/user-attachments/assets/938e879a-b7dd-44e5-a096-4c22f67b319b)

#### 相关Blog/文档

- [通过API 扩展在 Dify 上使用 Amazon Bedrock Guardrail 给聊天应用增加内容审查安全护栏](https://amzn-chn.feishu.cn/docx/PhNbdiDRDoj8vlxIDjAcKBlVncb)
- [集成Dify和AWS Service实现更具灵活性的翻译工作流](https://br5879sdns.feishu.cn/docx/Osehd7t5ZocVocxhtQycBHDCnfb)
- [在Dify上使用AWS中的DeepSeek 模型](https://amzn-chn.feishu.cn/docx/BtLHdxaG5o9xL6xXZcyciZUCn0f)

#### 动手实验

- [Rapidly Build GenAI Apps with Dify](https://catalog.us-east-1.prod.workshops.aws/workshops/2c19fcb1-1f1c-4f52-b759-0ca4d2ae2522/zh-CN)
- [硅基流动+DeepSeek+Dify workshop](https://catalog.us-east-1.prod.workshops.aws/workshops/87e070e2-5621-4c94-9285-529514ec4454/en-US)

================================================
FILE: builtin_tools/aws/aws.py
================================================
from core.tools.errors import ToolProviderCredentialValidationError
from core.tools.provider.builtin.aws.tools.sagemaker_text_rerank import SageMakerReRankTool
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController


class SageMakerProvider(BuiltinToolProviderController):
    def _validate_credentials(self, credentials: dict) -> None:
        try:
            SageMakerReRankTool().fork_tool_runtime(
                runtime={
                    "credentials": credentials,
                }
            ).invoke(
                user_id="",
                tool_parameters={
                    "sagemaker_endpoint": "",
                    "query": "misaka mikoto",
                    "candidate_texts": "hello$$$hello world",
                    "topk": 5,
                    "aws_region": "",
                },
            )
        except Exception as e:
            raise ToolProviderCredentialValidationError(str(e))


================================================
FILE: builtin_tools/aws/aws.yaml
================================================
identity:
  author: AWS
  name: aws
  label:
    en_US: AWS
    zh_Hans: 亚马逊云科技
    pt_BR: AWS
  description:
    en_US: Services on AWS.
    zh_Hans: 亚马逊云科技的各类服务
    pt_BR: Services on AWS.
  icon: icon.svg
  tags:
    - search
credentials_for_provider:


================================================
FILE: builtin_tools/aws/tools/apply_guardrail.py
================================================
import json
import logging
from typing import Any, Union

import boto3  # type: ignore
from botocore.exceptions import BotoCoreError  # type: ignore
from pydantic import BaseModel, Field

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class GuardrailParameters(BaseModel):
    guardrail_id: str = Field(..., description="The identifier of the guardrail")
    guardrail_version: str = Field(..., description="The version of the guardrail")
    source: str = Field(..., description="The source of the content")
    text: str = Field(..., description="The text to apply the guardrail to")
    aws_region: str = Field(..., description="AWS region for the Bedrock client")


class ApplyGuardrailTool(BuiltinTool):
    def _invoke(
        self, user_id: str, tool_parameters: dict[str, Any]
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        Invoke the ApplyGuardrail tool
        """
        try:
            # Validate and parse input parameters
            params = GuardrailParameters(**tool_parameters)

            # Initialize AWS client
            bedrock_client = boto3.client("bedrock-runtime", region_name=params.aws_region)

            # Apply guardrail
            response = bedrock_client.apply_guardrail(
                guardrailIdentifier=params.guardrail_id,
                guardrailVersion=params.guardrail_version,
                source=params.source,
                content=[{"text": {"text": params.text}}],
            )

            logger.info(f"Raw response from AWS: {json.dumps(response, indent=2)}")

            # Check for empty response
            if not response:
                return self.create_text_message(text="Received empty response from AWS Bedrock.")

            # Process the result
            action = response.get("action", "No action specified")
            outputs = response.get("outputs", [])
            output = outputs[0].get("text", "No output received") if outputs else "No output received"
            assessments = response.get("assessments", [])

            # Format assessments
            formatted_assessments = []
            for assessment in assessments:
                for policy_type, policy_data in assessment.items():
                    if isinstance(policy_data, dict) and "topics" in policy_data:
                        for topic in policy_data["topics"]:
                            formatted_assessments.append(
                                f"Policy: {policy_type}, Topic: {topic['name']}, Type: {topic['type']},"
                                f" Action: {topic['action']}"
                            )
                    else:
                        formatted_assessments.append(f"Policy: {policy_type}, Data: {policy_data}")

            result = f"Action: {action}\n "
            result += f"Output: {output}\n "
            if formatted_assessments:
                result += "Assessments:\n " + "\n ".join(formatted_assessments) + "\n "
            #           result += f"Full response: {json.dumps(response, indent=2, ensure_ascii=False)}"

            return self.create_text_message(text=result)

        except BotoCoreError as e:
            error_message = f"AWS service error: {str(e)}"
            logger.error(error_message, exc_info=True)
            return self.create_text_message(text=error_message)
        except json.JSONDecodeError as e:
            error_message = f"JSON parsing error: {str(e)}"
            logger.error(error_message, exc_info=True)
            return self.create_text_message(text=error_message)
        except Exception as e:
            error_message = f"An unexpected error occurred: {str(e)}"
            logger.error(error_message, exc_info=True)
            return self.create_text_message(text=error_message)


================================================
FILE: builtin_tools/aws/tools/apply_guardrail.yaml
================================================
identity:
  name: apply_guardrail
  author: AWS
  label:
    en_US: Content Moderation Guardrails
    zh_Hans: 内容审查护栏
description:
  human:
    en_US: Content Moderation Guardrails utilizes the ApplyGuardrail API, a feature of Guardrails for Amazon Bedrock. This API is capable of evaluating input prompts and model responses for all Foundation Models (FMs), including those on Amazon Bedrock, custom FMs, and third-party FMs. By implementing this functionality, organizations can achieve centralized governance across all their generative AI applications, thereby enhancing control and consistency in content moderation.
    zh_Hans: 内容审查护栏采用 Guardrails for Amazon Bedrock 功能中的 ApplyGuardrail API 。ApplyGuardrail 可以评估所有基础模型(FMs)的输入提示和模型响应,包括 Amazon Bedrock 上的 FMs、自定义 FMs 和第三方 FMs。通过实施这一功能, 组织可以在所有生成式 AI 应用程序中实现集中化的治理,从而增强内容审核的控制力和一致性。
  llm: Content Moderation Guardrails utilizes the ApplyGuardrail API, a feature of Guardrails for Amazon Bedrock. This API is capable of evaluating input prompts and model responses for all Foundation Models (FMs), including those on Amazon Bedrock, custom FMs, and third-party FMs. By implementing this functionality, organizations can achieve centralized governance across all their generative AI applications, thereby enhancing control and consistency in content moderation.
parameters:
  - name: guardrail_id
    type: string
    required: true
    label:
      en_US: Guardrail ID
      zh_Hans: Guardrail ID
    human_description:
      en_US: Please enter the ID of the Guardrail that has already been created on Amazon Bedrock, for example 'qk5nk0e4b77b'.
      zh_Hans: 请输入已经在 Amazon Bedrock 上创建好的 Guardrail ID, 例如 'qk5nk0e4b77b'.
    llm_description: Please enter the ID of the Guardrail that has already been created on Amazon Bedrock, for example 'qk5nk0e4b77b'.
    form: form
  - name: guardrail_version
    type: string
    required: true
    label:
      en_US: Guardrail Version Number
      zh_Hans: Guardrail 版本号码
    human_description:
      en_US: Please enter the published version of the Guardrail ID that has already been created on Amazon Bedrock. This is typically a version number, such as 2.
      zh_Hans: 请输入已经在Amazon Bedrock 上创建好的Guardrail ID发布的版本, 通常使用版本号, 例如2.
    llm_description: Please enter the published version of the Guardrail ID that has already been created on Amazon Bedrock. This is typically a version number, such as 2.
    form: form
  - name: source
    type: string
    required: true
    label:
      en_US: Content Source (INPUT or OUTPUT)
      zh_Hans: 内容来源 (INPUT or OUTPUT)
    human_description:
      en_US: The source of data used in the request to apply the guardrail. Valid Values "INPUT | OUTPUT"
      zh_Hans: 用于应用护栏的请求中所使用的数据来源。有效值为 "INPUT | OUTPUT"
    llm_description: The source of data used in the request to apply the guardrail. Valid Values "INPUT | OUTPUT"
    form: form
  - name: text
    type: string
    required: true
    label:
      en_US: Content to be reviewed
      zh_Hans: 待审查内容
    human_description:
      en_US: The content used for requesting guardrail review, which can be either user input or LLM output.
      zh_Hans: 用于请求护栏审查的内容,可以是用户输入或 LLM 输出。
    llm_description: The content used for requesting guardrail review, which can be either user input or LLM output.
    form: llm
  - name: aws_region
    type: string
    required: true
    label:
      en_US: AWS Region
      zh_Hans: AWS 区域
    human_description:
      en_US: Please enter the AWS region for the Bedrock client, for example 'us-east-1'.
      zh_Hans: 请输入 Bedrock 客户端的 AWS 区域,例如 'us-east-1'。
    llm_description: Please enter the AWS region for the Bedrock client, for example 'us-east-1'.
    form: form


================================================
FILE: builtin_tools/aws/tools/bedrock_retrieve.py
================================================
import json
import operator
from typing import Any, Optional, Union

import boto3

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool


class BedrockRetrieveTool(BuiltinTool):
    bedrock_client: Any = None
    knowledge_base_id: str = None
    topk: int = None

    def _bedrock_retrieve(
        self,
        query_input: str,
        knowledge_base_id: str,
        num_results: int,
        search_type: str,
        rerank_model_id: str,
        metadata_filter: Optional[dict] = None,
    ):
        try:
            retrieval_query = {"text": query_input}

            if search_type not in ["HYBRID", "SEMANTIC"]:
                raise RuntimeException("search_type should be HYBRID or SEMANTIC")

            retrieval_configuration = {
                "vectorSearchConfiguration": {"numberOfResults": num_results, "overrideSearchType": search_type}
            }

            if rerank_model_id != "default":
                region = self.bedrock_client.meta.region_name
                model_for_rerank_arn = f"arn:aws:bedrock:{region}::foundation-model/{rerank_model_id}"
                rerankingConfiguration = {
                    "bedrockRerankingConfiguration": {
                        "numberOfRerankedResults": num_results,
                        "modelConfiguration": {"modelArn": model_for_rerank_arn},
                    },
                    "type": "BEDROCK_RERANKING_MODEL",
                }

                retrieval_configuration["vectorSearchConfiguration"]["rerankingConfiguration"] = rerankingConfiguration
                retrieval_configuration["vectorSearchConfiguration"]["numberOfResults"] = num_results * 5

            # 如果有元数据过滤条件,则添加到检索配置中
            if metadata_filter:
                retrieval_configuration["vectorSearchConfiguration"]["filter"] = metadata_filter

            response = self.bedrock_client.retrieve(
                knowledgeBaseId=knowledge_base_id,
                retrievalQuery=retrieval_query,
                retrievalConfiguration=retrieval_configuration,
            )

            results = []
            for result in response.get("retrievalResults", []):
                results.append(
                    {
                        "content": result.get("content", {}).get("text", ""),
                        "score": result.get("score", 0.0),
                        "metadata": result.get("metadata", {}),
                    }
                )

            return results
        except Exception as e:
            raise Exception(f"Error retrieving from knowledge base: {str(e)}")

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        try:
            line = 0
            # Initialize Bedrock client if not already initialized
            if not self.bedrock_client:
                aws_region = tool_parameters.get("aws_region")
                aws_access_key_id = tool_parameters.get("aws_access_key_id")
                aws_secret_access_key = tool_parameters.get("aws_secret_access_key")

                client_kwargs = {"service_name": "bedrock-agent-runtime", "region_name": aws_region or None}

                # Only add credentials if both access key and secret key are provided
                if aws_access_key_id and aws_secret_access_key:
                    client_kwargs.update(
                        {"aws_access_key_id": aws_access_key_id, "aws_secret_access_key": aws_secret_access_key}
                    )

                self.bedrock_client = boto3.client(**client_kwargs)
        except Exception as e:
            return self.create_text_message(f"Failed to initialize Bedrock client: {str(e)}")

        try:
            line = 1
            if not self.knowledge_base_id:
                self.knowledge_base_id = tool_parameters.get("knowledge_base_id")
                if not self.knowledge_base_id:
                    return self.create_text_message("Please provide knowledge_base_id")

            line = 2
            if not self.topk:
                self.topk = tool_parameters.get("topk", 5)

            line = 3
            query = tool_parameters.get("query", "")
            if not query:
                return self.create_text_message("Please input query")

            # 获取元数据过滤条件(如果存在)
            metadata_filter_str = tool_parameters.get("metadata_filter")
            metadata_filter = json.loads(metadata_filter_str) if metadata_filter_str else None

            search_type = tool_parameters.get("search_type")
            rerank_model_id = tool_parameters.get("rerank_model_id")

            line = 4
            retrieved_docs = self._bedrock_retrieve(
                query_input=query,
                knowledge_base_id=self.knowledge_base_id,
                num_results=self.topk,
                search_type=search_type,
                rerank_model_id=rerank_model_id,
                metadata_filter=metadata_filter,
            )

            line = 5
            # Sort results by score in descending order
            sorted_docs = sorted(retrieved_docs, key=operator.itemgetter("score"), reverse=True)

            line = 6
            result_type = tool_parameters.get("result_type")
            if result_type == "json":
                return [self.create_json_message(res) for res in sorted_docs]
            else:
                text = ""
                for i, res in enumerate(sorted_docs):
                    text += f"{i + 1}: {res['content']}\n"
                return self.create_text_message(text)

        except Exception as e:
            return self.create_text_message(f"Exception {str(e)}, line : {line}")

    def validate_parameters(self, parameters: dict[str, Any]) -> None:
        """
        Validate the parameters
        """
        if not parameters.get("knowledge_base_id"):
            raise ValueError("knowledge_base_id is required")

        if not parameters.get("query"):
            raise ValueError("query is required")

        metadata_filter_str = parameters.get("metadata_filter")
        if metadata_filter_str and not isinstance(json.loads(metadata_filter_str), dict):
            raise ValueError("metadata_filter must be a valid JSON object")


================================================
FILE: builtin_tools/aws/tools/bedrock_retrieve.yaml
================================================
identity:
  name: bedrock_retrieve
  author: AWS
  label:
    en_US: Bedrock Retrieve
    zh_Hans: Bedrock检索
    pt_BR: Bedrock Retrieve
  icon: icon.svg

description:
  human:
    en_US: A tool for retrieving relevant information from Amazon Bedrock Knowledge Base. You can find deploy instructions on Github Repo - https://github.com/aws-samples/dify-aws-tool
    zh_Hans: Amazon Bedrock知识库检索工具, 请参考 Github Repo - https://github.com/aws-samples/dify-aws-tool上的部署说明
    pt_BR: A tool for retrieving relevant information from Amazon Bedrock Knowledge Base.
  llm: A tool for retrieving relevant information from Amazon Bedrock Knowledge Base. You can find deploy instructions on Github Repo - https://github.com/aws-samples/dify-aws-tool

parameters:
  - name: aws_region
    type: string
    required: false
    label:
      en_US: AWS Region
      zh_Hans: AWS区域
    human_description:
      en_US: AWS region for the Bedrock service
      zh_Hans: Bedrock服务的AWS区域
    form: form

  - name: aws_access_key_id
    type: string
    required: false
    label:
      en_US: AWS Access Key ID
      zh_Hans: AWS访问密钥ID
    human_description:
      en_US: AWS access key ID for authentication (optional)
      zh_Hans: 用于身份验证的AWS访问密钥ID(可选)
    form: form

  - name: aws_secret_access_key
    type: string
    required: false
    label:
      en_US: AWS Secret Access Key
      zh_Hans: AWS秘密访问密钥
    human_description:
      en_US: AWS secret access key for authentication (optional)
      zh_Hans: 用于身份验证的AWS秘密访问密钥(可选)
    form: form

  - name: result_type
    type: select
    required: true
    label:
      en_US: result type
      zh_Hans: 结果类型
    human_description:
      en_US: return a list of json or texts
      zh_Hans: 返回一个列表,内容是json还是纯文本
    default: text
    options:
      - value: json
        label:
          en_US: JSON
          zh_Hans: JSON
      - value: text
        label:
          en_US: Text
          zh_Hans: 文本
    form: form

  - name: knowledge_base_id
    type: string
    required: true
    label:
      en_US: Bedrock Knowledge Base ID
      zh_Hans: Bedrock知识库ID
      pt_BR: Bedrock Knowledge Base ID
    human_description:
      en_US: ID of the Bedrock Knowledge Base to retrieve from
      zh_Hans: 用于检索的Bedrock知识库ID
      pt_BR: ID of the Bedrock Knowledge Base to retrieve from
    llm_description: ID of the Bedrock Knowledge Base to retrieve from
    form: form

  - name: query
    type: string
    required: true
    label:
      en_US: Query string
      zh_Hans: 查询语句
      pt_BR: Query string
    human_description:
      en_US: The search query to retrieve relevant information
      zh_Hans: 用于检索相关信息的查询语句
      pt_BR: The search query to retrieve relevant information
    llm_description: The search query to retrieve relevant information
    form: llm

  - name: topk
    type: number
    required: false
    form: form
    label:
      en_US: Limit for results count
      zh_Hans: 返回结果数量限制
      pt_BR: Limit for results count
    human_description:
      en_US: Maximum number of results to return
      zh_Hans: 最大返回结果数量
      pt_BR: Maximum number of results to return
    min: 1
    max: 10
    default: 5

  - name: search_type
    type: select
    required: false
    label:
      en_US: search type
      zh_Hans: 搜索类型
      pt_BR: search type
    human_description:
      en_US: search type
      zh_Hans: 搜索类型
      pt_BR: search type
    llm_description: search type
    default: SEMANTIC
    options:
      - value: SEMANTIC
        label:
          en_US: SEMANTIC
          zh_Hans: 语义搜索
      - value: HYBRID
        label:
          en_US: HYBRID
          zh_Hans: 混合搜索
    form: form

  - name: rerank_model_id
    type: select
    required: false
    label:
      en_US: rerank model id
      zh_Hans: 重拍模型ID
      pt_BR: rerank model id
    human_description:
      en_US: rerank model id
      zh_Hans: 重拍模型ID
      pt_BR: rerank model id
    llm_description: rerank model id
    default: default
    options:
      - value: default
        label:
          en_US: default
          zh_Hans: 默认
      - value: cohere.rerank-v3-5:0
        label:
          en_US: cohere.rerank-v3-5:0
          zh_Hans: cohere.rerank-v3-5:0
      - value: amazon.rerank-v1:0
        label:
          en_US: amazon.rerank-v1:0
          zh_Hans: amazon.rerank-v1:0
    form: form

  - name: metadata_filter   # Additional parameter for metadata filtering
    type: string            # String type, expects JSON-formatted filter conditions
    required: false         # Optional field - can be omitted
    label:
      en_US: Metadata Filter
      zh_Hans: 元数据过滤器
      pt_BR: Metadata Filter
    human_description:
      en_US: 'JSON formatted filter conditions for metadata (e.g., {"greaterThan": {"key: "aaa", "value": 10}})'
      zh_Hans: '元数据的JSON格式过滤条件(例如,{{"greaterThan": {"key: "aaa", "value": 10}})'
      pt_BR: 'JSON formatted filter conditions for metadata (e.g., {"greaterThan": {"key: "aaa", "value": 10}})'
    form: form


================================================
FILE: builtin_tools/aws/tools/bedrock_retrieve_and_generate.py
================================================
import json
from typing import Any

import boto3

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool


class BedrockRetrieveAndGenerateTool(BuiltinTool):
    bedrock_client: Any = None

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> ToolInvokeMessage:
        try:
            # Initialize Bedrock client if not already initialized
            if not self.bedrock_client:
                aws_region = tool_parameters.get("aws_region")
                aws_access_key_id = tool_parameters.get("aws_access_key_id")
                aws_secret_access_key = tool_parameters.get("aws_secret_access_key")

                client_kwargs = {"service_name": "bedrock-agent-runtime", "region_name": aws_region or None}

                # Only add credentials if both access key and secret key are provided
                if aws_access_key_id and aws_secret_access_key:
                    client_kwargs.update(
                        {"aws_access_key_id": aws_access_key_id, "aws_secret_access_key": aws_secret_access_key}
                    )

                self.bedrock_client = boto3.client(**client_kwargs)
        except Exception as e:
            return self.create_text_message(f"Failed to initialize Bedrock client: {str(e)}")

        try:
            request_config = {}

            # Set input configuration
            input_text = tool_parameters.get("input")
            if input_text:
                request_config["input"] = {"text": input_text}

            # Build retrieve and generate configuration
            config_type = tool_parameters.get("type")
            retrieve_generate_config = {"type": config_type}

            # Add configuration based on type
            if config_type == "KNOWLEDGE_BASE":
                kb_config_str = tool_parameters.get("knowledge_base_configuration")
                kb_config = json.loads(kb_config_str) if kb_config_str else None
                retrieve_generate_config["knowledgeBaseConfiguration"] = kb_config
            else:  # EXTERNAL_SOURCES
                es_config_str = tool_parameters.get("external_sources_configuration")
                es_config = json.loads(kb_config_str) if es_config_str else None
                retrieve_generate_config["externalSourcesConfiguration"] = es_config

            request_config["retrieveAndGenerateConfiguration"] = retrieve_generate_config

            # Parse session configuration
            session_config_str = tool_parameters.get("session_configuration")
            session_config = json.loads(session_config_str) if session_config_str else None
            if session_config:
                request_config["sessionConfiguration"] = session_config

            # Add session ID if provided
            session_id = tool_parameters.get("session_id")
            if session_id:
                request_config["sessionId"] = session_id

            # Send request
            response = self.bedrock_client.retrieve_and_generate(**request_config)

            # Process response
            result = {"output": response.get("output", {}).get("text", ""), "citations": []}

            # Process citations
            for citation in response.get("citations", []):
                citation_info = {
                    "text": citation.get("generatedResponsePart", {}).get("textResponsePart", {}).get("text", ""),
                    "references": [],
                }

                for ref in citation.get("retrievedReferences", []):
                    reference = {
                        "content": ref.get("content", {}).get("text", ""),
                        "metadata": ref.get("metadata", {}),
                        "location": None,
                    }

                    location = ref.get("location", {})
                    if location.get("type") == "S3":
                        reference["location"] = location.get("s3Location", {}).get("uri")

                    citation_info["references"].append(reference)

                result["citations"].append(citation_info)
            result_type = tool_parameters.get("result_type")
            if result_type == "json":
                return self.create_json_message(result)
            elif result_type == "text-with-citations":
                return self.create_text_message(result)
            else:
                return self.create_text_message(result.get("output"))
        except json.JSONDecodeError as e:
            return self.create_text_message(f"Invalid JSON format: {str(e)}")
        except Exception as e:
            return self.create_text_message(f"Tool invocation error: {str(e)}")

    def validate_parameters(self, parameters: dict[str, Any]) -> None:
        """Validate the parameters"""
        # Validate required parameters
        if not parameters.get("input"):
            raise ValueError("input is required")
        if not parameters.get("type"):
            raise ValueError("type is required")

        # Validate JSON configurations
        json_configs = ["knowledge_base_configuration", "external_sources_configuration", "session_configuration"]
        for config in json_configs:
            if config_value := parameters.get(config):
                try:
                    json.loads(config_value)
                except json.JSONDecodeError:
                    raise ValueError(f"{config} must be a valid JSON string")

        # Validate configuration type
        config_type = parameters.get("type")
        if config_type not in ["KNOWLEDGE_BASE", "EXTERNAL_SOURCES"]:
            raise ValueError("type must be either KNOWLEDGE_BASE or EXTERNAL_SOURCES")

        # Validate type-specific configuration
        if config_type == "KNOWLEDGE_BASE" and not parameters.get("knowledge_base_configuration"):
            raise ValueError("knowledge_base_configuration is required when type is KNOWLEDGE_BASE")
        elif config_type == "EXTERNAL_SOURCES" and not parameters.get("external_sources_configuration"):
            raise ValueError("external_sources_configuration is required when type is EXTERNAL_SOURCES")


================================================
FILE: builtin_tools/aws/tools/bedrock_retrieve_and_generate.yaml
================================================
identity:
  name: bedrock_retrieve_and_generate
  author: AWS
  label:
    en_US: Bedrock Retrieve and Generate
    zh_Hans: Bedrock检索和生成
  icon: icon.svg

description:
  human:
    en_US: "This is an advanced usage of Bedrock Retrieve. Please refer to the API documentation for detailed parameters and paste them into the corresponding Knowledge Base Configuration or External Sources Configuration"
    zh_Hans: "这个工具为Bedrock Retrieve的高级用法,请参考API设置详细的参数,并粘贴到对应的知识库配置或者外部源配置"
  llm: A tool for retrieving and generating information using Amazon Bedrock Knowledge Base

parameters:
  - name: aws_region
    type: string
    required: false
    label:
      en_US: AWS Region
      zh_Hans: AWS区域
    human_description:
      en_US: AWS region for the Bedrock service
      zh_Hans: Bedrock服务的AWS区域
    form: form

  - name: aws_access_key_id
    type: string
    required: false
    label:
      en_US: AWS Access Key ID
      zh_Hans: AWS访问密钥ID
    human_description:
      en_US: AWS access key ID for authentication (optional)
      zh_Hans: 用于身份验证的AWS访问密钥ID(可选)
    form: form

  - name: aws_secret_access_key
    type: string
    required: false
    label:
      en_US: AWS Secret Access Key
      zh_Hans: AWS秘密访问密钥
    human_description:
      en_US: AWS secret access key for authentication (optional)
      zh_Hans: 用于身份验证的AWS秘密访问密钥(可选)
    form: form

  - name: result_type
    type: select
    required: true
    label:
      en_US: result type
      zh_Hans: 结果类型
    human_description:
      en_US: return a list of json or texts
      zh_Hans: 返回一个列表,内容是json还是纯文本
    default: text
    options:
      - value: json
        label:
          en_US: JSON
          zh_Hans: JSON
      - value: text
        label:
          en_US: Text
          zh_Hans: 文本
      - value: text-with-citations
        label:
          en_US: Text With Citations
          zh_Hans: 文本(包含引用)
    form: form

  - name: input
    type: string
    required: true
    label:
      en_US: Input Text
      zh_Hans: 输入文本
    human_description:
      en_US: The text query to retrieve information
      zh_Hans: 用于检索信息的文本查询
    form: llm

  - name: type
    type: select
    required: true
    label:
      en_US: Configuration Type
      zh_Hans: 配置类型
    human_description:
      en_US: Type of retrieve and generate configuration
      zh_Hans: 检索和生成配置的类型
    options:
      - value: KNOWLEDGE_BASE
        label:
          en_US: Knowledge Base
          zh_Hans: 知识库
      - value: EXTERNAL_SOURCES
        label:
          en_US: External Sources
          zh_Hans: 外部源
    form: form

  - name: knowledge_base_configuration
    type: string
    required: false
    label:
      en_US: Knowledge Base Configuration
      zh_Hans: 知识库配置
    human_description:
      en_US: Please refer to @https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-agent-runtime/client/retrieve_and_generate.html#retrieve-and-generate for complete parameters and paste them here
      zh_Hans: 请参考 https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-agent-runtime/client/retrieve_and_generate.html#retrieve-and-generate 配置完整的参数并粘贴到这里
    form: form

  - name: external_sources_configuration
    type: string
    required: false
    label:
      en_US: External Sources Configuration
      zh_Hans: 外部源配置
    human_description:
      en_US: Please refer to https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-agent-runtime/client/retrieve_and_generate.html#retrieve-and-generate for complete parameters and paste them here
      zh_Hans: 请参考 https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-agent-runtime/client/retrieve_and_generate.html#retrieve-and-generate 配置完整的参数并粘贴到这里
    form: form

  - name: session_configuration
    type: string
    required: false
    label:
      en_US: Session Configuration
      zh_Hans: 会话配置
    human_description:
      en_US: JSON formatted session configuration
      zh_Hans: JSON格式的会话配置
    default: ""
    form: form

  - name: session_id
    type: string
    required: false
    label:
      en_US: Session ID
      zh_Hans: 会话ID
    human_description:
      en_US: Session ID for continuous conversations
      zh_Hans: 用于连续对话的会话ID
    form: form


================================================
FILE: builtin_tools/aws/tools/extract_frame.py
================================================
import os
import json
import logging
import shutil
import requests
from PIL import Image
from typing import Any, Union

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class FrameExtractor(BuiltinTool):
    def _extract_specific_frames(self, gif_path, output_folder, frame_count=5):
        """
        从GIF中提取特定数量的帧(均匀分布)
        
        Args:
            gif_path (str): GIF文件的路径
            output_folder (str): 保存提取帧的输出文件夹路径
            frame_count (int): 要提取的帧数,默认为5
            
        Returns:
            list: 提取的帧的路径列表
        """
        # 创建输出文件夹(如果不存在)
        os.makedirs(output_folder, exist_ok=True)
        
        # 打开GIF文件
        gif = Image.open(gif_path)
        
        # 获取总帧数
        total_frames = gif.n_frames
        print(f"GIF共有 {total_frames} 帧")
        
        # 计算要提取哪些帧
        if frame_count == 2:
            # 如果只要2帧,则提取首帧和尾帧
            frames_to_extract = [0, total_frames - 1]
        else:
            # 否则均匀分布提取帧
            if frame_count >= total_frames:
                # 如果要提取的帧数大于等于总帧数,则提取所有帧
                frames_to_extract = list(range(total_frames))
            else:
                # 均匀分布提取帧
                step = (total_frames - 1) / (frame_count - 1) if frame_count > 1 else 0
                frames_to_extract = [int(i * step) for i in range(frame_count)]
                # 确保包含最后一帧
                if frames_to_extract[-1] != total_frames - 1:
                    frames_to_extract[-1] = total_frames - 1
        
        # 提取并保存指定的帧
        extracted_paths = []
        for i, frame_idx in enumerate(frames_to_extract):
            gif.seek(frame_idx)
            frame = gif.copy()
            output_path = os.path.join(output_folder, f"frame_{i:03d}.png")
            frame.save(output_path)
            extracted_paths.append(output_path)
            print(f"已保存第 {frame_idx+1}/{total_frames} 帧 (索引 {frame_idx})")
        
        print(f"已提取 {len(extracted_paths)} 帧!")
        return extracted_paths

    def _clean_temp_dir(self, temp_dir):
        """
        清理临时目录
        
        Args:
            temp_dir (str): 临时目录路径
        """
        try:
            if os.path.exists(temp_dir):
                shutil.rmtree(temp_dir)
                print(f"已删除临时目录: {temp_dir}")
        except Exception as e:
            print(f"删除临时目录时出错: {str(e)}")

    def _invoke(
        self, 
        user_id: str, 
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        temp_dir = os.path.join(os.path.dirname(__file__), "temp")
        try:
            input_url = tool_parameters.get("input_url")
            frame_count = int(tool_parameters.get("frame_count", 5))  # 默认提取5帧
            input_type = tool_parameters.get("input_type", "GIF")  # 默认为GIF类型
            
            # 创建临时文件夹
            os.makedirs(temp_dir, exist_ok=True)
            
            # 临时GIF文件路径
            gif_path = os.path.join(temp_dir, "input.gif")
            output_folder = os.path.join(temp_dir, "frames")
            
            # 根据输入类型处理
            if input_type == "GIF":
                # 从URL下载GIF
                response = requests.get(input_url, stream=True)
                if response.status_code == 200:
                    with open(gif_path, 'wb') as f:
                        for chunk in response.iter_content(chunk_size=8192):
                            f.write(chunk)
                else:
                    return self.create_text_message(f"下载GIF失败 - {input_url},状态码: {response.status_code}")
            else:
                return self.create_text_message(f"只支持GIF格式。")
            
            # 提取特定数量的帧
            extracted_paths = self._extract_specific_frames(gif_path, output_folder, frame_count)
            
            # 返回提取的帧
            frame_messages = []
            for path in extracted_paths:
                with open(path, 'rb') as f:
                    frame_content = f.read()
                    frame_messages.append(self.create_blob_message(
                        blob=frame_content, 
                        meta={"mime_type": "image/png"}
                    ))
            return frame_messages
                    
        except Exception as e:
            return self.create_text_message(f"提取帧时出错: {str(e)}")
        finally:
            # 无论成功还是失败,都清理临时目录
            self._clean_temp_dir(temp_dir)


================================================
FILE: builtin_tools/aws/tools/extract_frame.yaml
================================================
identity:
  name: extract_frame
  author: AWS
  label:
    en_US: ExtractFrame
    zh_Hans: 抽帧工具
    pt_BR: ExtractFrame
  icon: icon.svg
description:
  human:
    en_US: A extract frame tool for LLM
    zh_Hans: 为大模型提供抽帧处理
    pt_BR: A extract frame tool for LLM
  llm: A extract frame tool.
parameters:
  - name: input_url
    type: string
    required: true
    label:
      en_US: input url
      zh_Hans: 输入 url
      pt_BR: input url
    human_description:
      en_US: input url(video/gif)
      zh_Hans: 输入 url video/gif)
      pt_BR: input url video/gif)
    llm_description: input url video/gif)
    form: llm
  - name: frame_count
    type: number
    required: true
    label:
      en_US: Frame count
      zh_Hans: 帧数(2帧即首帧+尾帧,5帧即首尾帧+中间帧)
    human_description:
      en_US: Frame count
      zh_Hans: 帧数
    form: form
    default: 2
  - name: input_type
    type: select
    required: true
    label:
      en_US: input type
      zh_Hans: 请求类型
      pt_BR: input type
    human_description:
      en_US: input type
      zh_Hans: 请求类型
      pt_BR: input type
    default: GIF
    options:
      - value: GIF
        label:
          en_US: GIF
          zh_Hans: GIF
    form: form

================================================
FILE: builtin_tools/aws/tools/lambda_translate_utils.py
================================================
import json
from typing import Any, Union

import boto3  # type: ignore

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool


class LambdaTranslateUtilsTool(BuiltinTool):
    lambda_client: Any = None

    def _invoke_lambda(self, text_content, src_lang, dest_lang, model_id, dictionary_name, request_type, lambda_name):
        msg = {
            "src_contents": [text_content],
            "src_lang": src_lang,
            "dest_lang": dest_lang,
            "dictionary_id": dictionary_name,
            "request_type": request_type,
            "model_id": model_id,
        }

        invoke_response = self.lambda_client.invoke(
            FunctionName=lambda_name, InvocationType="RequestResponse", Payload=json.dumps(msg)
        )
        response_body = invoke_response["Payload"]

        response_str = response_body.read().decode("unicode_escape")

        return response_str

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        line = 0
        try:
            if not self.lambda_client:
                aws_region = tool_parameters.get("aws_region")
                if aws_region:
                    self.lambda_client = boto3.client("lambda", region_name=aws_region)
                else:
                    self.lambda_client = boto3.client("lambda")

            line = 1
            text_content = tool_parameters.get("text_content", "")
            if not text_content:
                return self.create_text_message("Please input text_content")

            line = 2
            src_lang = tool_parameters.get("src_lang", "")
            if not src_lang:
                return self.create_text_message("Please input src_lang")

            line = 3
            dest_lang = tool_parameters.get("dest_lang", "")
            if not dest_lang:
                return self.create_text_message("Please input dest_lang")

            line = 4
            lambda_name = tool_parameters.get("lambda_name", "")
            if not lambda_name:
                return self.create_text_message("Please input lambda_name")

            line = 5
            request_type = tool_parameters.get("request_type", "")
            if not request_type:
                return self.create_text_message("Please input request_type")

            line = 6
            model_id = tool_parameters.get("model_id", "")
            if not model_id:
                return self.create_text_message("Please input model_id")

            line = 7
            dictionary_name = tool_parameters.get("dictionary_name", "")
            if not dictionary_name:
                return self.create_text_message("Please input dictionary_name")

            result = self._invoke_lambda(
                text_content, src_lang, dest_lang, model_id, dictionary_name, request_type, lambda_name
            )

            return self.create_text_message(text=result)

        except Exception as e:
            return self.create_text_message(f"Exception {str(e)}, line : {line}")


================================================
FILE: builtin_tools/aws/tools/lambda_translate_utils.yaml
================================================
identity:
  name: lambda_translate_utils
  author: AWS
  label:
    en_US: TranslateTool
    zh_Hans: 翻译工具
    pt_BR: TranslateTool
  icon: icon.svg
description:
  human:
    en_US: A util tools for LLM translation, extra deployment is needed on AWS. Please refer Github Repo - https://github.com/aws-samples/rag-based-translation-with-dynamodb-and-bedrock
    zh_Hans: 大语言模型翻译工具(专词映射获取),需要在AWS上进行额外部署,可参考Github Repo - https://github.com/aws-samples/rag-based-translation-with-dynamodb-and-bedrock
    pt_BR: A util tools for LLM translation, specific Lambda Function deployment is needed on AWS. Please refer Github Repo - https://github.com/aws-samples/rag-based-translation-with-dynamodb-and-bedrock
  llm: A util tools for translation.
parameters:
  - name: text_content
    type: string
    required: true
    label:
      en_US: source content for translation
      zh_Hans: 待翻译原文
      pt_BR: source content for translation
    human_description:
      en_US: source content for translation
      zh_Hans: 待翻译原文
      pt_BR: source content for translation
    llm_description: source content for translation
    form: llm
  - name: src_lang
    type: string
    required: true
    label:
      en_US: source language code
      zh_Hans: 原文语言代号
      pt_BR: source language code
    human_description:
      en_US: source language code
      zh_Hans: 原文语言代号
      pt_BR: source language code
    llm_description: source language code
    form: llm
  - name: dest_lang
    type: string
    required: true
    label:
      en_US: target language code
      zh_Hans: 目标语言代号
      pt_BR: target language code
    human_description:
      en_US: target language code
      zh_Hans: 目标语言代号
      pt_BR: target language code
    llm_description: target language code
    form: llm
  - name: aws_region
    type: string
    required: false
    label:
      en_US: region of Lambda
      zh_Hans: Lambda 所在的region
      pt_BR: region of Lambda
    human_description:
      en_US: region of Lambda
      zh_Hans: Lambda 所在的region
      pt_BR: region of Lambda
    llm_description: region of Lambda
    form: form
  - name: model_id
    type: string
    required: false
    default: anthropic.claude-3-sonnet-20240229-v1:0
    label:
      en_US: LLM model_id in bedrock
      zh_Hans: bedrock上的大语言模型model_id
      pt_BR: LLM model_id in bedrock
    human_description:
      en_US: LLM model_id in bedrock
      zh_Hans: bedrock上的大语言模型model_id
      pt_BR: LLM model_id in bedrock
    llm_description: LLM model_id in bedrock
    form: form
  - name: dictionary_name
    type: string
    required: false
    label:
      en_US: dictionary name for term mapping
      zh_Hans: 专词映射表名称
      pt_BR: dictionary name for term mapping
    human_description:
      en_US: dictionary name for term mapping
      zh_Hans: 专词映射表名称
      pt_BR: dictionary name for term mapping
    llm_description: dictionary name for term mapping
    form: form
  - name: request_type
    type: select
    required: false
    label:
      en_US: request type
      zh_Hans: 请求类型
      pt_BR: request type
    human_description:
      en_US: request type
      zh_Hans: 请求类型
      pt_BR: request type
    default: term_mapping
    options:
      - value: term_mapping
        label:
          en_US: term_mapping
          zh_Hans: 专词映射
      - value: segment_only
        label:
          en_US: segment_only
          zh_Hans: 仅切词
      - value: translate
        label:
          en_US: translate
          zh_Hans: 翻译内容
    form: form
  - name: lambda_name
    type: string
    default: "translate_tool"
    required: true
    label:
      en_US: AWS Lambda for term mapping retrieval
      zh_Hans: 专词召回映射 - AWS Lambda
      pt_BR: lambda name for term mapping retrieval
    human_description:
      en_US: AWS Lambda  for term mapping retrieval
      zh_Hans: 专词召回映射 - AWS Lambda
      pt_BR: AWS Lambda  for term mapping retrieval
    llm_description: AWS Lambda  for term mapping retrieval
    form: form


================================================
FILE: builtin_tools/aws/tools/lambda_yaml_to_json.py
================================================
import json
import logging
from typing import Any, Union

import boto3  # type: ignore

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

console_handler = logging.StreamHandler()
logger.addHandler(console_handler)


class LambdaYamlToJsonTool(BuiltinTool):
    lambda_client: Any = None

    def _invoke_lambda(self, lambda_name: str, yaml_content: str) -> str:
        msg = {"body": yaml_content}
        logger.info(json.dumps(msg))

        invoke_response = self.lambda_client.invoke(
            FunctionName=lambda_name, InvocationType="RequestResponse", Payload=json.dumps(msg)
        )
        response_body = invoke_response["Payload"]

        response_str = response_body.read().decode("utf-8")
        resp_json = json.loads(response_str)

        logger.info(resp_json)
        if resp_json["statusCode"] != 200:
            raise Exception(f"Invalid status code: {response_str}")

        return resp_json["body"]

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        try:
            if not self.lambda_client:
                aws_region = tool_parameters.get("aws_region")  # todo: move aws_region out, and update client region
                if aws_region:
                    self.lambda_client = boto3.client("lambda", region_name=aws_region)
                else:
                    self.lambda_client = boto3.client("lambda")

            yaml_content = tool_parameters.get("yaml_content", "")
            if not yaml_content:
                return self.create_text_message("Please input yaml_content")

            lambda_name = tool_parameters.get("lambda_name", "")
            if not lambda_name:
                return self.create_text_message("Please input lambda_name")
            logger.debug(f"{json.dumps(tool_parameters, indent=2, ensure_ascii=False)}")

            result = self._invoke_lambda(lambda_name, yaml_content)
            logger.debug(result)

            return self.create_text_message(result)
        except Exception as e:
            return self.create_text_message(f"Exception: {str(e)}")

        console_handler.flush()


================================================
FILE: builtin_tools/aws/tools/lambda_yaml_to_json.yaml
================================================
identity:
  name: lambda_yaml_to_json
  author: AWS
  label:
    en_US: LambdaYamlToJson
    zh_Hans: LambdaYamlToJson
    pt_BR: LambdaYamlToJson
  icon: icon.svg
description:
  human:
    en_US: A tool to convert yaml to json using AWS Lambda.
    zh_Hans: 将 YAML 转为 JSON 的工具(通过AWS Lambda)。
    pt_BR: A tool to convert yaml to json using AWS Lambda.
  llm: A tool to convert yaml to json.
parameters:
  - name: yaml_content
    type: string
    required: true
    label:
      en_US: YAML content to convert for
      zh_Hans: YAML 内容
      pt_BR: YAML content to convert for
    human_description:
      en_US: YAML content to convert for
      zh_Hans: YAML 内容
      pt_BR: YAML content to convert for
    llm_description: YAML content to convert for
    form: llm
  - name: aws_region
    type: string
    required: false
    label:
      en_US: region of lambda
      zh_Hans: Lambda 所在的region
      pt_BR: region of lambda
    human_description:
      en_US: region of lambda
      zh_Hans: Lambda 所在的region
      pt_BR: region of lambda
    llm_description: region of lambda
    form: form
  - name: lambda_name
    type: string
    required: false
    label:
      en_US: name of lambda
      zh_Hans: Lambda 名称
      pt_BR: name of lambda
    human_description:
      en_US: name of lambda
      zh_Hans: Lambda 名称
      pt_BR: name of lambda
    form: form


================================================
FILE: builtin_tools/aws/tools/nova_canvas.py
================================================
import base64
import json
import logging
import re
from datetime import datetime
from typing import Any, Union
from urllib.parse import urlparse

import boto3

from core.tools.entities.common_entities import I18nObject
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter
from core.tools.tool.builtin_tool import BuiltinTool

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class NovaCanvasTool(BuiltinTool):
    def _invoke(
        self, user_id: str, tool_parameters: dict[str, Any]
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        Invoke AWS Bedrock Nova Canvas model for image generation
        """
        # Get common parameters
        prompt = tool_parameters.get("prompt", "")
        image_output_s3uri = tool_parameters.get("image_output_s3uri", "").strip()
        if not prompt:
            return self.create_text_message("Please provide a text prompt for image generation.")
        if not image_output_s3uri or urlparse(image_output_s3uri).scheme != "s3":
            return self.create_text_message("Please provide an valid S3 URI for image output.")

        task_type = tool_parameters.get("task_type", "TEXT_IMAGE")
        aws_region = tool_parameters.get("aws_region", "us-east-1")

        # Get common image generation config parameters
        width = tool_parameters.get("width", 1024)
        height = tool_parameters.get("height", 1024)
        cfg_scale = tool_parameters.get("cfg_scale", 8.0)
        negative_prompt = tool_parameters.get("negative_prompt", "")
        seed = tool_parameters.get("seed", 0)
        quality = tool_parameters.get("quality", "standard")

        # Handle S3 image if provided
        image_input_s3uri = tool_parameters.get("image_input_s3uri", "")
        if task_type != "TEXT_IMAGE":
            if not image_input_s3uri or urlparse(image_input_s3uri).scheme != "s3":
                return self.create_text_message("Please provide a valid S3 URI for image to image generation.")

            # Parse S3 URI
            parsed_uri = urlparse(image_input_s3uri)
            bucket = parsed_uri.netloc
            key = parsed_uri.path.lstrip("/")

            # Initialize S3 client and download image
            s3_client = boto3.client("s3")
            response = s3_client.get_object(Bucket=bucket, Key=key)
            image_data = response["Body"].read()

            # Base64 encode the image
            input_image = base64.b64encode(image_data).decode("utf-8")

        try:
            # Initialize Bedrock client
            bedrock = boto3.client(service_name="bedrock-runtime", region_name=aws_region)

            # Base image generation config
            image_generation_config = {
                "width": width,
                "height": height,
                "cfgScale": cfg_scale,
                "seed": seed,
                "numberOfImages": 1,
                "quality": quality,
            }

            # Prepare request body based on task type
            body = {"imageGenerationConfig": image_generation_config}

            if task_type == "TEXT_IMAGE":
                body["taskType"] = "TEXT_IMAGE"
                body["textToImageParams"] = {"text": prompt}
                if negative_prompt:
                    body["textToImageParams"]["negativeText"] = negative_prompt

            elif task_type == "COLOR_GUIDED_GENERATION":
                colors = tool_parameters.get("colors", "#ff8080-#ffb280-#ffe680-#ffe680")
                if not self._validate_color_string(colors):
                    return self.create_text_message("Please provide valid colors in hexadecimal format.")

                body["taskType"] = "COLOR_GUIDED_GENERATION"
                body["colorGuidedGenerationParams"] = {
                    "colors": colors.split("-"),
                    "referenceImage": input_image,
                    "text": prompt,
                }
                if negative_prompt:
                    body["colorGuidedGenerationParams"]["negativeText"] = negative_prompt

            elif task_type == "IMAGE_VARIATION":
                similarity_strength = tool_parameters.get("similarity_strength", 0.5)

                body["taskType"] = "IMAGE_VARIATION"
                body["imageVariationParams"] = {
                    "images": [input_image],
                    "similarityStrength": similarity_strength,
                    "text": prompt,
                }
                if negative_prompt:
                    body["imageVariationParams"]["negativeText"] = negative_prompt

            elif task_type == "INPAINTING":
                mask_prompt = tool_parameters.get("mask_prompt")
                if not mask_prompt:
                    return self.create_text_message("Please provide a mask prompt for image inpainting.")

                body["taskType"] = "INPAINTING"
                body["inPaintingParams"] = {"image": input_image, "maskPrompt": mask_prompt, "text": prompt}
                if negative_prompt:
                    body["inPaintingParams"]["negativeText"] = negative_prompt

            elif task_type == "OUTPAINTING":
                mask_prompt = tool_parameters.get("mask_prompt")
                if not mask_prompt:
                    return self.create_text_message("Please provide a mask prompt for image outpainting.")
                outpainting_mode = tool_parameters.get("outpainting_mode", "DEFAULT")

                body["taskType"] = "OUTPAINTING"
                body["outPaintingParams"] = {
                    "image": input_image,
                    "maskPrompt": mask_prompt,
                    "outPaintingMode": outpainting_mode,
                    "text": prompt,
                }
                if negative_prompt:
                    body["outPaintingParams"]["negativeText"] = negative_prompt

            elif task_type == "BACKGROUND_REMOVAL":
                body["taskType"] = "BACKGROUND_REMOVAL"
                body["backgroundRemovalParams"] = {"image": input_image}

            else:
                return self.create_text_message(f"Unsupported task type: {task_type}")

            # Call Nova Canvas model
            response = bedrock.invoke_model(
                body=json.dumps(body),
                modelId="amazon.nova-canvas-v1:0",
                accept="application/json",
                contentType="application/json",
            )

            # Process response
            response_body = json.loads(response.get("body").read())
            if response_body.get("error"):
                raise Exception(f"Error in model response: {response_body.get('error')}")
            base64_image = response_body.get("images")[0]

            # Upload to S3 if image_output_s3uri is provided
            try:
                # Parse S3 URI for output
                parsed_uri = urlparse(image_output_s3uri)
                output_bucket = parsed_uri.netloc
                output_base_path = parsed_uri.path.lstrip("/")
                # Generate filename with timestamp
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                output_key = f"{output_base_path}/canvas-output-{timestamp}.png"

                # Initialize S3 client if not already done
                s3_client = boto3.client("s3", region_name=aws_region)

                # Decode base64 image and upload to S3
                image_data = base64.b64decode(base64_image)
                s3_client.put_object(Bucket=output_bucket, Key=output_key, Body=image_data, ContentType="image/png")
                logger.info(f"Image uploaded to s3://{output_bucket}/{output_key}")
            except Exception as e:
                logger.exception("Failed to upload image to S3")
            # Return image
            return [
                self.create_text_message(f"Image is available at: s3://{output_bucket}/{output_key}"),
                self.create_blob_message(
                    blob=base64.b64decode(base64_image),
                    meta={"mime_type": "image/png"},
                    save_as=self.VariableKey.IMAGE.value,
                ),
            ]

        except Exception as e:
            return self.create_text_message(f"Failed to generate image: {str(e)}")

    def _validate_color_string(self, color_string) -> bool:
        color_pattern = r"^#[0-9a-fA-F]{6}(?:-#[0-9a-fA-F]{6})*$"

        if re.match(color_pattern, color_string):
            return True
        return False

    def get_runtime_parameters(self) -> list[ToolParameter]:
        parameters = [
            ToolParameter(
                name="prompt",
                label=I18nObject(en_US="Prompt", zh_Hans="提示词"),
                type=ToolParameter.ToolParameterType.STRING,
                required=True,
                form=ToolParameter.ToolParameterForm.LLM,
                human_description=I18nObject(
                    en_US="Text description of the image you want to generate or modify",
                    zh_Hans="您想要生成或修改的图像的文本描述",
                ),
                llm_description="Describe the image you want to generate or how you want to modify the input image",
            ),
            ToolParameter(
                name="image_input_s3uri",
                label=I18nObject(en_US="Input image s3 uri", zh_Hans="输入图片的s3 uri"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                form=ToolParameter.ToolParameterForm.LLM,
                human_description=I18nObject(en_US="Image to be modified", zh_Hans="想要修改的图片"),
            ),
            ToolParameter(
                name="image_output_s3uri",
                label=I18nObject(en_US="Output Image S3 URI", zh_Hans="输出图片的S3 URI目录"),
                type=ToolParameter.ToolParameterType.STRING,
                required=True,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(
                    en_US="S3 URI where the generated image should be uploaded", zh_Hans="生成的图像应该上传到的S3 URI"
                ),
            ),
            ToolParameter(
                name="width",
                label=I18nObject(en_US="Width", zh_Hans="宽度"),
                type=ToolParameter.ToolParameterType.NUMBER,
                required=False,
                default=1024,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(en_US="Width of the generated image", zh_Hans="生成图像的宽度"),
            ),
            ToolParameter(
                name="height",
                label=I18nObject(en_US="Height", zh_Hans="高度"),
                type=ToolParameter.ToolParameterType.NUMBER,
                required=False,
                default=1024,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(en_US="Height of the generated image", zh_Hans="生成图像的高度"),
            ),
            ToolParameter(
                name="cfg_scale",
                label=I18nObject(en_US="CFG Scale", zh_Hans="CFG比例"),
                type=ToolParameter.ToolParameterType.NUMBER,
                required=False,
                default=8.0,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(
                    en_US="How strongly the image should conform to the prompt", zh_Hans="图像应该多大程度上符合提示词"
                ),
            ),
            ToolParameter(
                name="negative_prompt",
                label=I18nObject(en_US="Negative Prompt", zh_Hans="负面提示词"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                default="",
                form=ToolParameter.ToolParameterForm.LLM,
                human_description=I18nObject(
                    en_US="Things you don't want in the generated image", zh_Hans="您不想在生成的图像中出现的内容"
                ),
            ),
            ToolParameter(
                name="seed",
                label=I18nObject(en_US="Seed", zh_Hans="种子值"),
                type=ToolParameter.ToolParameterType.NUMBER,
                required=False,
                default=0,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(en_US="Random seed for image generation", zh_Hans="图像生成的随机种子"),
            ),
            ToolParameter(
                name="aws_region",
                label=I18nObject(en_US="AWS Region", zh_Hans="AWS 区域"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                default="us-east-1",
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(en_US="AWS region for Bedrock service", zh_Hans="Bedrock 服务的 AWS 区域"),
            ),
            ToolParameter(
                name="task_type",
                label=I18nObject(en_US="Task Type", zh_Hans="任务类型"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                default="TEXT_IMAGE",
                form=ToolParameter.ToolParameterForm.LLM,
                human_description=I18nObject(en_US="Type of image generation task", zh_Hans="图像生成任务的类型"),
            ),
            ToolParameter(
                name="quality",
                label=I18nObject(en_US="Quality", zh_Hans="质量"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                default="standard",
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(
                    en_US="Quality of the generated image (standard or premium)", zh_Hans="生成图像的质量(标准或高级)"
                ),
            ),
            ToolParameter(
                name="colors",
                label=I18nObject(en_US="Colors", zh_Hans="颜色"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(
                    en_US="List of colors for color-guided generation, example: #ff8080-#ffb280-#ffe680-#ffe680",
                    zh_Hans="颜色引导生成的颜色列表, 例子: #ff8080-#ffb280-#ffe680-#ffe680",
                ),
            ),
            ToolParameter(
                name="similarity_strength",
                label=I18nObject(en_US="Similarity Strength", zh_Hans="相似度强度"),
                type=ToolParameter.ToolParameterType.NUMBER,
                required=False,
                default=0.5,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(
                    en_US="How similar the generated image should be to the input image (0.0 to 1.0)",
                    zh_Hans="生成的图像应该与输入图像的相似程度(0.0到1.0)",
                ),
            ),
            ToolParameter(
                name="mask_prompt",
                label=I18nObject(en_US="Mask Prompt", zh_Hans="蒙版提示词"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                form=ToolParameter.ToolParameterForm.LLM,
                human_description=I18nObject(
                    en_US="Text description to generate mask for inpainting/outpainting",
                    zh_Hans="用于生成内补绘制/外补绘制蒙版的文本描述",
                ),
            ),
            ToolParameter(
                name="outpainting_mode",
                label=I18nObject(en_US="Outpainting Mode", zh_Hans="外补绘制模式"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                default="DEFAULT",
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(
                    en_US="Mode for outpainting (DEFAULT or other supported modes)",
                    zh_Hans="外补绘制的模式(DEFAULT或其他支持的模式)",
                ),
            ),
        ]

        return parameters


================================================
FILE: builtin_tools/aws/tools/nova_canvas.yaml
================================================
identity:
  name: nova_canvas
  author: AWS
  label:
    en_US: AWS Bedrock Nova Canvas
    zh_Hans: AWS Bedrock Nova Canvas
  icon: icon.svg
description:
  human:
    en_US: A tool for generating and modifying images using AWS Bedrock's Nova Canvas model. Supports text-to-image, color-guided generation, image variation, inpainting, outpainting, and background removal. Input parameters reference https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html
    zh_Hans: 使用 AWS Bedrock 的 Nova Canvas 模型生成和修改图像的工具。支持文生图、颜色引导生成、图像变体、内补绘制、外补绘制和背景移除功能, 输入参数参考 https://docs.aws.amazon.com/nova/latest/userguide/image-gen-req-resp-structure.html。
  llm: Generate or modify images using AWS Bedrock's Nova Canvas model with multiple task types including text-to-image, color-guided generation, image variation, inpainting, outpainting, and background removal.
parameters:
  - name: task_type
    type: string
    required: false
    default: TEXT_IMAGE
    label:
      en_US: Task Type
      zh_Hans: 任务类型
    human_description:
      en_US: Type of image generation task (TEXT_IMAGE, COLOR_GUIDED_GENERATION, IMAGE_VARIATION, INPAINTING, OUTPAINTING, BACKGROUND_REMOVAL)
      zh_Hans: 图像生成任务的类型(文生图、颜色引导生成、图像变体、内补绘制、外补绘制、背景移除)
    form: llm
  - name: prompt
    type: string
    required: true
    label:
      en_US: Prompt
      zh_Hans: 提示词
    human_description:
      en_US: Text description of the image you want to generate or modify
      zh_Hans: 您想要生成或修改的图像的文本描述
    llm_description: Describe the image you want to generate or how you want to modify the input image
    form: llm
  - name: image_input_s3uri
    type: string
    required: false
    label:
      en_US: Input image s3 uri
      zh_Hans: 输入图片的s3 uri
    human_description:
      en_US: The input image to modify (required for all modes except TEXT_IMAGE)
      zh_Hans: 要修改的输入图像(除文生图外的所有模式都需要)
    llm_description: The input image you want to modify. Required for all modes except TEXT_IMAGE.
    form: llm
  - name: image_output_s3uri
    type: string
    required: true
    label:
      en_US: Output S3 URI
      zh_Hans: 输出S3 URI
    human_description:
      en_US: The S3 URI where the generated image will be saved. If provided, the image will be uploaded with name format canvas-output-{timestamp}.png
      zh_Hans: 生成的图像将保存到的S3 URI。如果提供,图像将以canvas-output-{timestamp}.png的格式上传
    llm_description: Optional S3 URI where the generated image will be uploaded. The image will be saved with a timestamp-based filename.
    form: form
  - name: negative_prompt
    type: string
    required: false
    label:
      en_US: Negative Prompt
      zh_Hans: 负面提示词
    human_description:
      en_US: Things you don't want in the generated image
      zh_Hans: 您不想在生成的图像中出现的内容
    form: llm
  - name: width
    type: number
    required: false
    label:
      en_US: Width
      zh_Hans: 宽度
    human_description:
      en_US: Width of the generated image
      zh_Hans: 生成图像的宽度
    form: form
    default: 1024
  - name: height
    type: number
    required: false
    label:
      en_US: Height
      zh_Hans: 高度
    human_description:
      en_US: Height of the generated image
      zh_Hans: 生成图像的高度
    form: form
    default: 1024
  - name: cfg_scale
    type: number
    required: false
    label:
      en_US: CFG Scale
      zh_Hans: CFG比例
    human_description:
      en_US: How strongly the image should conform to the prompt
      zh_Hans: 图像应该多大程度上符合提示词
    form: form
    default: 8.0
  - name: seed
    type: number
    required: false
    label:
      en_US: Seed
      zh_Hans: 种子值
    human_description:
      en_US: Random seed for image generation
      zh_Hans: 图像生成的随机种子
    form: form
    default: 0
  - name: aws_region
    type: string
    required: false
    default: us-east-1
    label:
      en_US: AWS Region
      zh_Hans: AWS 区域
    human_description:
      en_US: AWS region for Bedrock service
      zh_Hans: Bedrock 服务的 AWS 区域
    form: form
  - name: quality
    type: string
    required: false
    default: standard
    label:
      en_US: Quality
      zh_Hans: 质量
    human_description:
      en_US: Quality of the generated image (standard or premium)
      zh_Hans: 生成图像的质量(标准或高级)
    form: form
  - name: colors
    type: string
    required: false
    label:
      en_US: Colors
      zh_Hans: 颜色
    human_description:
      en_US: List of colors for color-guided generation
      zh_Hans: 颜色引导生成的颜色列表
    form: form
  - name: similarity_strength
    type: number
    required: false
    default: 0.5
    label:
      en_US: Similarity Strength
      zh_Hans: 相似度强度
    human_description:
      en_US: How similar the generated image should be to the input image (0.0 to 1.0)
      zh_Hans: 生成的图像应该与输入图像的相似程度(0.0到1.0)
    form: form
  - name: mask_prompt
    type: string
    required: false
    label:
      en_US: Mask Prompt
      zh_Hans: 蒙版提示词
    human_description:
      en_US: Text description to generate mask for inpainting/outpainting
      zh_Hans: 用于生成内补绘制/外补绘制蒙版的文本描述
    form: llm
  - name: outpainting_mode
    type: string
    required: false
    default: DEFAULT
    label:
      en_US: Outpainting Mode
      zh_Hans: 外补绘制模式
    human_description:
      en_US: Mode for outpainting (DEFAULT or other supported modes)
      zh_Hans: 外补绘制的模式(DEFAULT或其他支持的模式)
    form: form


================================================
FILE: builtin_tools/aws/tools/nova_reel.py
================================================
import base64
import logging
import time
from io import BytesIO
from typing import Any, Optional, Union
from urllib.parse import urlparse

import boto3
from botocore.exceptions import ClientError
from PIL import Image

from core.tools.entities.common_entities import I18nObject
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter
from core.tools.tool.builtin_tool import BuiltinTool

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

NOVA_REEL_DEFAULT_REGION = "us-east-1"
NOVA_REEL_DEFAULT_DIMENSION = "1280x720"
NOVA_REEL_DEFAULT_FPS = 24
NOVA_REEL_DEFAULT_DURATION = 6
NOVA_REEL_MODEL_ID = "amazon.nova-reel-v1:0"
NOVA_REEL_STATUS_CHECK_INTERVAL = 5

# Image requirements
NOVA_REEL_REQUIRED_IMAGE_WIDTH = 1280
NOVA_REEL_REQUIRED_IMAGE_HEIGHT = 720
NOVA_REEL_REQUIRED_IMAGE_MODE = "RGB"


class NovaReelTool(BuiltinTool):
    def _invoke(
        self, user_id: str, tool_parameters: dict[str, Any]
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        Invoke AWS Bedrock Nova Reel model for video generation.

        Args:
            user_id: The ID of the user making the request
            tool_parameters: Dictionary containing the tool parameters

        Returns:
            ToolInvokeMessage containing either the video content or status information
        """
        try:
            # Validate and extract parameters
            params = self._validate_and_extract_parameters(tool_parameters)
            if isinstance(params, ToolInvokeMessage):
                return params

            # Initialize AWS clients
            bedrock, s3_client = self._initialize_aws_clients(params["aws_region"])

            # Prepare model input
            model_input = self._prepare_model_input(params, s3_client)
            if isinstance(model_input, ToolInvokeMessage):
                return model_input

            # Start video generation
            invocation = self._start_video_generation(bedrock, model_input, params["video_output_s3uri"])
            invocation_arn = invocation["invocationArn"]

            # Handle async/sync mode
            return self._handle_generation_mode(bedrock, s3_client, invocation_arn, params["async_mode"])

        except ClientError as e:
            error_code = e.response.get("Error", {}).get("Code", "Unknown")
            error_message = e.response.get("Error", {}).get("Message", str(e))
            logger.exception(f"AWS API error: {error_code} - {error_message}")
            return self.create_text_message(f"AWS service error: {error_code} - {error_message}")
        except Exception as e:
            logger.error(f"Unexpected error in video generation: {str(e)}", exc_info=True)
            return self.create_text_message(f"Failed to generate video: {str(e)}")

    def _validate_and_extract_parameters(
        self, tool_parameters: dict[str, Any]
    ) -> Union[dict[str, Any], ToolInvokeMessage]:
        """Validate and extract parameters from the input dictionary."""
        prompt = tool_parameters.get("prompt", "")
        video_output_s3uri = tool_parameters.get("video_output_s3uri", "").strip()

        # Validate required parameters
        if not prompt:
            return self.create_text_message("Please provide a text prompt for video generation.")
        if not video_output_s3uri:
            return self.create_text_message("Please provide an S3 URI for video output.")

        # Validate S3 URI format
        if not video_output_s3uri.startswith("s3://"):
            return self.create_text_message("Invalid S3 URI format. Must start with 's3://'")

        # Ensure S3 URI ends with '/'
        video_output_s3uri = video_output_s3uri if video_output_s3uri.endswith("/") else video_output_s3uri + "/"

        return {
            "prompt": prompt,
            "video_output_s3uri": video_output_s3uri,
            "image_input_s3uri": tool_parameters.get("image_input_s3uri", "").strip(),
            "aws_region": tool_parameters.get("aws_region", NOVA_REEL_DEFAULT_REGION),
            "dimension": tool_parameters.get("dimension", NOVA_REEL_DEFAULT_DIMENSION),
            "seed": int(tool_parameters.get("seed", 0)),
            "fps": int(tool_parameters.get("fps", NOVA_REEL_DEFAULT_FPS)),
            "duration": int(tool_parameters.get("duration", NOVA_REEL_DEFAULT_DURATION)),
            "async_mode": bool(tool_parameters.get("async", True)),
        }

    def _initialize_aws_clients(self, region: str) -> tuple[Any, Any]:
        """Initialize AWS Bedrock and S3 clients."""
        bedrock = boto3.client(service_name="bedrock-runtime", region_name=region)
        s3_client = boto3.client("s3", region_name=region)
        return bedrock, s3_client

    def _prepare_model_input(self, params: dict[str, Any], s3_client: Any) -> Union[dict[str, Any], ToolInvokeMessage]:
        """Prepare the input for the Nova Reel model."""
        model_input = {
            "taskType": "TEXT_VIDEO",
            "textToVideoParams": {"text": params["prompt"]},
            "videoGenerationConfig": {
                "durationSeconds": params["duration"],
                "fps": params["fps"],
                "dimension": params["dimension"],
                "seed": params["seed"],
            },
        }

        # Add image if provided
        if params["image_input_s3uri"]:
            try:
                image_data = self._get_image_from_s3(s3_client, params["image_input_s3uri"])
                if not image_data:
                    return self.create_text_message("Failed to retrieve image from S3")

                # Process and validate image
                processed_image = self._process_and_validate_image(image_data)
                if isinstance(processed_image, ToolInvokeMessage):
                    return processed_image

                # Convert processed image to base64
                img_buffer = BytesIO()
                processed_image.save(img_buffer, format="PNG")
                img_buffer.seek(0)
                input_image_base64 = base64.b64encode(img_buffer.getvalue()).decode("utf-8")

                model_input["textToVideoParams"]["images"] = [
                    {"format": "png", "source": {"bytes": input_image_base64}}
                ]
            except Exception as e:
                logger.error(f"Error processing input image: {str(e)}", exc_info=True)
                return self.create_text_message(f"Failed to process input image: {str(e)}")

        return model_input

    def _process_and_validate_image(self, image_data: bytes) -> Union[Image.Image, ToolInvokeMessage]:
        """
        Process and validate the input image according to Nova Reel requirements.

        Requirements:
        - Must be 1280x720 pixels
        - Must be RGB format (8 bits per channel)
        - If PNG, alpha channel must not have transparent/translucent pixels
        """
        try:
            # Open image
            img = Image.open(BytesIO(image_data))

            # Convert RGBA to RGB if needed, ensuring no transparency
            if img.mode == "RGBA":
                # Check for transparency
                if img.getchannel("A").getextrema()[0] < 255:
                    return self.create_text_message(
                        "PNG image contains transparent or translucent pixels, which is not supported. "
                        "Please provide an image without transparency."
                    )
                # Convert to RGB
                img = img.convert("RGB")
            elif img.mode != "RGB":
                # Convert any other mode to RGB
                img = img.convert("RGB")

            # Validate/adjust dimensions
            if img.size != (NOVA_REEL_REQUIRED_IMAGE_WIDTH, NOVA_REEL_REQUIRED_IMAGE_HEIGHT):
                logger.warning(
                    f"Image dimensions {img.size} do not match required dimensions "
                    f"({NOVA_REEL_REQUIRED_IMAGE_WIDTH}x{NOVA_REEL_REQUIRED_IMAGE_HEIGHT}). Resizing..."
                )
                img = img.resize(
                    (NOVA_REEL_REQUIRED_IMAGE_WIDTH, NOVA_REEL_REQUIRED_IMAGE_HEIGHT), Image.Resampling.LANCZOS
                )

            # Validate bit depth
            if img.mode != NOVA_REEL_REQUIRED_IMAGE_MODE:
                return self.create_text_message(
                    f"Image must be in {NOVA_REEL_REQUIRED_IMAGE_MODE} mode with 8 bits per channel"
                )

            return img

        except Exception as e:
            logger.error(f"Error processing image: {str(e)}", exc_info=True)
            return self.create_text_message(
                "Failed to process image. Please ensure the image is a valid JPEG or PNG file."
            )

    def _get_image_from_s3(self, s3_client: Any, s3_uri: str) -> Optional[bytes]:
        """Download and return image data from S3."""
        parsed_uri = urlparse(s3_uri)
        bucket = parsed_uri.netloc
        key = parsed_uri.path.lstrip("/")

        response = s3_client.get_object(Bucket=bucket, Key=key)
        return response["Body"].read()

    def _start_video_generation(self, bedrock: Any, model_input: dict[str, Any], output_s3uri: str) -> dict[str, Any]:
        """Start the async video generation process."""
        return bedrock.start_async_invoke(
            modelId=NOVA_REEL_MODEL_ID,
            modelInput=model_input,
            outputDataConfig={"s3OutputDataConfig": {"s3Uri": output_s3uri}},
        )

    def _handle_generation_mode(
        self, bedrock: Any, s3_client: Any, invocation_arn: str, async_mode: bool
    ) -> ToolInvokeMessage:
        """Handle async or sync video generation mode."""
        invocation_response = bedrock.get_async_invoke(invocationArn=invocation_arn)
        video_path = invocation_response["outputDataConfig"]["s3OutputDataConfig"]["s3Uri"]
        video_uri = f"{video_path}/output.mp4"

        if async_mode:
            return self.create_text_message(
                f"Video generation started.\nInvocation ARN: {invocation_arn}\nVideo will be available at: {video_uri}"
            )

        return self._wait_for_completion(bedrock, s3_client, invocation_arn)

    def _wait_for_completion(self, bedrock: Any, s3_client: Any, invocation_arn: str) -> ToolInvokeMessage:
        """Wait for video generation completion and handle the result."""
        while True:
            status_response = bedrock.get_async_invoke(invocationArn=invocation_arn)
            status = status_response["status"]
            video_path = status_response["outputDataConfig"]["s3OutputDataConfig"]["s3Uri"]

            if status == "Completed":
                return self._handle_completed_video(s3_client, video_path)
            elif status == "Failed":
                failure_message = status_response.get("failureMessage", "Unknown error")
                return self.create_text_message(f"Video generation failed.\nError: {failure_message}")
            elif status == "InProgress":
                time.sleep(NOVA_REEL_STATUS_CHECK_INTERVAL)
            else:
                return self.create_text_message(f"Unexpected status: {status}")

    def _handle_completed_video(self, s3_client: Any, video_path: str) -> ToolInvokeMessage:
        """Handle completed video generation and return the result."""
        parsed_uri = urlparse(video_path)
        bucket = parsed_uri.netloc
        key = parsed_uri.path.lstrip("/") + "/output.mp4"

        try:
            response = s3_client.get_object(Bucket=bucket, Key=key)
            video_content = response["Body"].read()
            return [
                self.create_text_message(f"Video is available at: {video_path}/output.mp4"),
                self.create_blob_message(blob=video_content, meta={"mime_type": "video/mp4"}, save_as="output.mp4"),
            ]
        except Exception as e:
            logger.error(f"Error downloading video: {str(e)}", exc_info=True)
            return self.create_text_message(
                f"Video generation completed but failed to download video: {str(e)}\n"
                f"Video is available at: s3://{bucket}/{key}"
            )

    def get_runtime_parameters(self) -> list[ToolParameter]:
        """Define the tool's runtime parameters."""
        parameters = [
            ToolParameter(
                name="prompt",
                label=I18nObject(en_US="Prompt", zh_Hans="提示词"),
                type=ToolParameter.ToolParameterType.STRING,
                required=True,
                form=ToolParameter.ToolParameterForm.LLM,
                human_description=I18nObject(
                    en_US="Text description of the video you want to generate", zh_Hans="您想要生成的视频的文本描述"
                ),
                llm_description="Describe the video you want to generate",
            ),
            ToolParameter(
                name="video_output_s3uri",
                label=I18nObject(en_US="Output S3 URI", zh_Hans="输出S3 URI"),
                type=ToolParameter.ToolParameterType.STRING,
                required=True,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(
                    en_US="S3 URI where the generated video will be stored", zh_Hans="生成的视频将存储的S3 URI"
                ),
            ),
            ToolParameter(
                name="dimension",
                label=I18nObject(en_US="Dimension", zh_Hans="尺寸"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                default=NOVA_REEL_DEFAULT_DIMENSION,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(en_US="Video dimensions (width x height)", zh_Hans="视频尺寸(宽 x 高)"),
            ),
            ToolParameter(
                name="duration",
                label=I18nObject(en_US="Duration", zh_Hans="时长"),
                type=ToolParameter.ToolParameterType.NUMBER,
                required=False,
                default=NOVA_REEL_DEFAULT_DURATION,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(en_US="Video duration in seconds", zh_Hans="视频时长(秒)"),
            ),
            ToolParameter(
                name="seed",
                label=I18nObject(en_US="Seed", zh_Hans="种子值"),
                type=ToolParameter.ToolParameterType.NUMBER,
                required=False,
                default=0,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(en_US="Random seed for video generation", zh_Hans="视频生成的随机种子"),
            ),
            ToolParameter(
                name="fps",
                label=I18nObject(en_US="FPS", zh_Hans="帧率"),
                type=ToolParameter.ToolParameterType.NUMBER,
                required=False,
                default=NOVA_REEL_DEFAULT_FPS,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(
                    en_US="Frames per second for the generated video", zh_Hans="生成视频的每秒帧数"
                ),
            ),
            ToolParameter(
                name="async",
                label=I18nObject(en_US="Async Mode", zh_Hans="异步模式"),
                type=ToolParameter.ToolParameterType.BOOLEAN,
                required=False,
                default=True,
                form=ToolParameter.ToolParameterForm.LLM,
                human_description=I18nObject(
                    en_US="Whether to run in async mode (return immediately) or sync mode (wait for completion)",
                    zh_Hans="是否以异步模式运行(立即返回)或同步模式(等待完成)",
                ),
            ),
            ToolParameter(
                name="aws_region",
                label=I18nObject(en_US="AWS Region", zh_Hans="AWS 区域"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                default=NOVA_REEL_DEFAULT_REGION,
                form=ToolParameter.ToolParameterForm.FORM,
                human_description=I18nObject(en_US="AWS region for Bedrock service", zh_Hans="Bedrock 服务的 AWS 区域"),
            ),
            ToolParameter(
                name="image_input_s3uri",
                label=I18nObject(en_US="Input Image S3 URI", zh_Hans="输入图像S3 URI"),
                type=ToolParameter.ToolParameterType.STRING,
                required=False,
                form=ToolParameter.ToolParameterForm.LLM,
                human_description=I18nObject(
                    en_US="S3 URI of the input image (1280x720 JPEG/PNG) to use as first frame",
                    zh_Hans="用作第一帧的输入图像(1280x720 JPEG/PNG)的S3 URI",
                ),
            ),
        ]

        return parameters


================================================
FILE: builtin_tools/aws/tools/nova_reel.yaml
================================================
identity:
  name: nova_reel
  author: AWS
  label:
    en_US: AWS Bedrock Nova Reel
    zh_Hans: AWS Bedrock Nova Reel
  icon: icon.svg
description:
  human:
    en_US: A tool for generating videos using AWS Bedrock's Nova Reel model. Supports text-to-video generation and image-to-video generation with customizable parameters like duration, FPS, and dimensions. Input parameters reference https://docs.aws.amazon.com/nova/latest/userguide/video-generation.html
    zh_Hans: 使用 AWS Bedrock 的 Nova Reel 模型生成视频的工具。支持文本生成视频和图像生成视频功能,可自定义持续时间、帧率和尺寸等参数。输入参数参考 https://docs.aws.amazon.com/nova/latest/userguide/video-generation.html
  llm: Generate videos using AWS Bedrock's Nova Reel model with support for both text-to-video and image-to-video generation, allowing customization of video properties like duration, frame rate, and resolution.

parameters:
  - name: prompt
    type: string
    required: true
    label:
      en_US: Prompt
      zh_Hans: 提示词
    human_description:
      en_US: Text description of the video you want to generate
      zh_Hans: 您想要生成的视频的文本描述
    llm_description: Describe the video you want to generate
    form: llm

  - name: video_output_s3uri
    type: string
    required: true
    label:
      en_US: Output S3 URI
      zh_Hans: 输出S3 URI
    human_description:
      en_US: S3 URI where the generated video will be stored
      zh_Hans: 生成的视频将存储的S3 URI
    form: form

  - name: dimension
    type: string
    required: false
    default: 1280x720
    label:
      en_US: Dimension
      zh_Hans: 尺寸
    human_description:
      en_US: Video dimensions (width x height)
      zh_Hans: 视频尺寸(宽 x 高)
    form: form

  - name: duration
    type: number
    required: false
    default: 6
    label:
      en_US: Duration
      zh_Hans: 时长
    human_description:
      en_US: Video duration in seconds
      zh_Hans: 视频时长(秒)
    form: form

  - name: seed
    type: number
    required: false
    default: 0
    label:
      en_US: Seed
      zh_Hans: 种子值
    human_description:
      en_US: Random seed for video generation
      zh_Hans: 视频生成的随机种子
    form: form

  - name: fps
    type: number
    required: false
    default: 24
    label:
      en_US: FPS
      zh_Hans: 帧率
    human_description:
      en_US: Frames per second for the generated video
      zh_Hans: 生成视频的每秒帧数
    form: form

  - name: async
    type: boolean
    required: false
    default: true
    label:
      en_US: Async Mode
      zh_Hans: 异步模式
    human_description:
      en_US: Whether to run in async mode (return immediately) or sync mode (wait for completion)
      zh_Hans: 是否以异步模式运行(立即返回)或同步模式(等待完成)
    form: llm

  - name: aws_region
    type: string
    required: false
    default: us-east-1
    label:
      en_US: AWS Region
      zh_Hans: AWS 区域
    human_description:
      en_US: AWS region for Bedrock service
      zh_Hans: Bedrock 服务的 AWS 区域
    form: form

  - name: image_input_s3uri
    type: string
    required: false
    label:
      en_US: Input Image S3 URI
      zh_Hans: 输入图像S3 URI
    human_description:
      en_US: S3 URI of the input image (1280x720 JPEG/PNG) to use as first frame
      zh_Hans: 用作第一帧的输入图像(1280x720 JPEG/PNG)的S3 URI
    form: llm

development:
  dependencies:
    - boto3
    - pillow


================================================
FILE: builtin_tools/aws/tools/opensearch_knn_search.py
================================================
from typing import Any, Union
from urllib.parse import urlparse

import boto3
import json
import base64

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from requests_aws4auth import AWS4Auth
from opensearchpy import OpenSearch, RequestsHttpConnection

class OpenSearchRetrieveTool(BuiltinTool):
    os_client: Any = None
    bedrock_client: Any = None
    s3_client: Any = None

    def _get_embedding(self, model_id:str, text:str=None, image_path:str=None, dimension:int=1024):
        image_base64 = None

        def parse_s3_url(s3_url:str):
            if s3_url.startswith("s3://"):
                s3_url = s3_url[5:]

            parts = s3_url.split('/', 1)
            
            if len(parts) == 2:
                bucket_name = parts[0]
                object_key = parts[1]
            else:
                bucket_name = parts[0]
                object_key = ''
            
            return bucket_name, object_key

        if image_path:
            try:
                bucket_name, object_key = parse_s3_url(image_path)
                response = self.s3_client.get_object(Bucket=bucket_name, Key=object_key)
                image_content = response['Body'].read()
                image_base64 = base64.b64encode(image_content).decode('utf-8')
            except Exception as e:
                self.create_text_message(f"'{image_path}' is not valid image path")
                pass

        request_body = {}
        if text:
            request_body["inputText"] = text

        if image_base64:
            request_body["inputImage"] = image_base64

        embedding_config = {
            "embeddingConfig": { 
                 "outputEmbeddingLength": dimension
            }
        }
        body = json.dumps({**request_body, **embedding_config})
        response = self.bedrock_client.invoke_model(
            body=body,
            modelId=model_id,
            accept="application/json",
            contentType="application/json")
        response_body = json.loads(response.get("body").read())
        return response_body.get("embedding")

    def _search_by_aos_knn(self, q_embedding, index_name:str, embedding_field:str, meta_field_list:list[str], size:int=5):
        query = {
            "size": size,
            "query": {
                "knn": {
                    f"{embedding_field}" : {
                        "vector": q_embedding,
                        "k": size
                    }
                }
            }
        }

        opensearch_knn_respose = []
        query_response = self.os_client.search(
            body=query,
            index=index_name
        )

        results = []
        for item in query_response["hits"]["hits"]:
            result_obj = { field_name: item['_source'][field_name] for field_name in meta_field_list }
            result_obj['score'] = item['_score']
            results.append(result_obj)

        return results

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        try:
            aws_region = tool_parameters.get("aws_region")
            if not self.os_client:
                opensearch_endpoint = tool_parameters.get("opensearch_endpoint").replace("https://","")
                index_name = tool_parameters.get("index_name")

                credentials = boto3.Session().get_credentials()
                awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, aws_region, "aoss", session_token=credentials.token)

                # 创建 OpenSearch 客户端
                self.os_client = OpenSearch(
                    hosts=[{'host': opensearch_endpoint, 'port': 443}],
                    http_auth=awsauth,
                    use_ssl=True,
                    verify_certs=True,
                    connection_class=RequestsHttpConnection
                )
            if not self.s3_client:
                self.s3_client = boto3.client(service_name="s3", region_name=aws_region)

            if not self.bedrock_client:
                self.bedrock_client = boto3.client(service_name="bedrock-runtime", region_name=aws_region)

            emb_model_id = tool_parameters.get("embedding_model_id")
            embedding_field = tool_parameters.get("embedding_field")
            metadata_fields = tool_parameters.get("metadata_fields").split(",")
            image_s3_path = tool_parameters.get("image_s3_path")
            query_text = tool_parameters.get("query_text")
            vector_size = int(tool_parameters.get("vector_size"))
            topk = tool_parameters.get("topk")

            embedding = self._get_embedding(model_id=emb_model_id, 
                text=query_text, 
                image_path=image_s3_path, 
                dimension=vector_size
            )

            result = self._search_by_aos_knn(q_embedding=embedding, 
                index_name=index_name, 
                embedding_field=embedding_field, 
                meta_field_list=metadata_fields, 
                size=topk
            )

            return [ self.create_json_message(res) for res in result ]

        except Exception as e:
            return self.create_text_message(f"Exception: {str(e)}")

================================================
FILE: builtin_tools/aws/tools/opensearch_knn_search.yaml
================================================
identity:
  name: opensearch_retrieve
  author: AWS
  label:
    en_US: OpenSearch Retrieve
    zh_Hans: OpenSearch检索
    pt_BR: OpenSearch Retrieve
  icon: icon.svg

description:
  human:
    en_US: A tool for retrieving relevant information from Amazon OpenSearch.
    zh_Hans: Amazon OpenSearch 检索工具
    pt_BR: A tool for retrieving relevant information from Amazon OpenSearch.
  llm: A tool for retrieving relevant information from Amazon OpenSearch.

parameters:
  - name: opensearch_endpoint
    type: string
    required: true
    label:
      en_US: OpenSearch Endpoint
      zh_Hans: OpenSearch 端点
      pt_BR: OpenSearch Endpoint
    human_description:
      en_US: OpenSearch Endpoint
      zh_Hans: OpenSearch 端点
      pt_BR: OpenSearch Endpoint
    llm_description: OpenSearch Endpoint to retrieve from
    form: form

  - name: index_name
    type: string
    required: true
    label:
      en_US: Target Index Name
      zh_Hans: 目标索引名称
      pt_BR: Target Index Name
    human_description:
      en_US: Target Index Name
      zh_Hans: 目标索引名称
      pt_BR: Target Index Name
    llm_description: The target of index name
    form: form

  - name: image_s3_path
    type: string
    required: false
    label:
      en_US: Image S3 Path
      zh_Hans: 图像s3路径
      pt_BR: Image S3 Path
    human_description:
      en_US: Image S3 Path
      zh_Hans: 图像s3路径
      pt_BR: Image S3 Path
    llm_description: s3 path of image
    form: llm

  - name: query_text
    type: string
    required: false
    label:
      en_US: Query Text
      zh_Hans: 查询文本
      pt_BR: Query Text
    human_description:
      en_US: Query Text
      zh_Hans: 查询文本
      pt_BR: Query Text
    llm_description: query text
    form: llm

  - name: embedding_field
    type: string
    required: true
    default: pic_emb
    label:
      en_US: Embedding Field Name
      zh_Hans: 向量字段名称
      pt_BR: Embedding Field Name
    human_description:
      en_US: Embedding Field Name
      zh_Hans: 向量字段名称
      pt_BR: Embedding Field Name
    llm_description: embedding field name
    form: llm

  - name: metadata_fields
    type: string
    required: true
    default: s3_uri,pic_name
    label:
      en_US: Metadata Fields
      zh_Hans: 元信息字段列表
      pt_BR: Metadata Fields
    human_description:
      en_US: metadata fields
      zh_Hans: 元信息字段列表
      pt_BR: metadata fields
    llm_description: metadata fields
    form: llm

  - name: topk
    type: number
    required: false
    form: form
    label:
      en_US: Results Count
      zh_Hans: 结果数量
      pt_BR: Results Count
    human_description:
      en_US: Results Count
      zh_Hans: 结果数量
      pt_BR: Results Count
    min: 1
    max: 10
    default: 5

  - name: vector_size
    type: select
    required: true
    label:
      en_US: embedding size
      zh_Hans: 纬度 
      pt_BR: embedding size
    human_description:
      en_US: embedding size
      zh_Hans: 纬度
      pt_BR: embedding size
    llm_description: embedding size
    options:
      - value: '1024'
        label:
          en_US: '1024'
          zh_Hans: '1024'
      - value: '512'
        label:
          en_US: '512'
          zh_Hans: '512'
      - value: '384'
        label:
          en_US: '384'
          zh_Hans: '384'
      - value: '256'
        label:
          en_US: '256'
          zh_Hans: '256'
    form: form

  - name: search_type
    type: select
    required: false
    label:
      en_US: search type
      zh_Hans: 搜索类型
      pt_BR: search type
    human_description:
      en_US: search type
      zh_Hans: 搜索类型
      pt_BR: search type
    llm_description: search type
    default: SEMANTIC
    options:
      - value: SEMANTIC
        label:
          en_US: SEMANTIC
          zh_Hans: 语义搜索
    form: form

  - name: embedding_model_id
    type: select
    required: true
    label:
      en_US: Model Id
      zh_Hans: 向量模型ID
      pt_BR: Model Id
    human_description:
      en_US: Model Id
      zh_Hans: 向量模型ID
      pt_BR: Model Id
    llm_description: embedding model id
    options:
      - value: amazon.titan-embed-image-v1
        label:
          en_US: amazon.titan-embed-image-v1
          zh_Hans: amazon.titan-embed-image-v1
      - value: amazon.titan-embed-text-v1
        label:
          en_US: amazon.titan-embed-text-v1
          zh_Hans: amazon.titan-embed-text-v1
      - value: amazon.titan-embed-text-v2:0
        label:
          en_US: amazon.titan-embed-text-v2:0
          zh_Hans: amazon.titan-embed-text-v2:0
      - value: amazon.titan-embed-text-v2:0
        label:
          en_US: amazon.titan-embed-text-v2:0
          zh_Hans: amazon.titan-embed-text-v2:0
      - value: cohere.embed-english-v3
        label:
          en_US: cohere.embed-english-v3
          zh_Hans: cohere.embed-english-v3
      - value: cohere.embed-multilingual-v3
        label:
          en_US: cohere.embed-multilingual-v3
          zh_Hans: cohere.embed-multilingual-v3
    form: form

  - name: aws_region
    type: string
    required: false
    label:
      en_US: AWS Region
      zh_Hans: AWS 区域
      pt_BR: AWS Region
    human_description:
      en_US: AWS region where the Bedrock Knowledge Base is located
      zh_Hans: Bedrock知识库所在的AWS区域
      pt_BR: AWS region where the Bedrock Knowledge Base is located
    llm_description: AWS region where the Bedrock Knowledge Base is located
    form: form

================================================
FILE: builtin_tools/aws/tools/s3_operator.py
================================================
from typing import Any, Union
from urllib.parse import urlparse

import boto3

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool


class S3Operator(BuiltinTool):
    s3_client: Any = None

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        try:
            # Initialize S3 client if not already done
            if not self.s3_client:
                aws_region = tool_parameters.get("aws_region")
                if aws_region:
                    self.s3_client = boto3.client("s3", region_name=aws_region)
                else:
                    self.s3_client = boto3.client("s3")

            # Parse S3 URI
            s3_uri = tool_parameters.get("s3_uri")
            if not s3_uri:
                return self.create_text_message("s3_uri parameter is required")

            parsed_uri = urlparse(s3_uri)
            if parsed_uri.scheme != "s3":
                return self.create_text_message("Invalid S3 URI format. Must start with 's3://'")

            bucket = parsed_uri.netloc
            # Remove leading slash from key
            key = parsed_uri.path.lstrip("/")

            operation_type = tool_parameters.get("operation_type", "read")
            generate_presign_url = tool_parameters.get("generate_presign_url", False)
            presign_expiry = int(tool_parameters.get("presign_expiry", 3600))  # default 1 hour

            if operation_type == "write":
                text_content = tool_parameters.get("text_content")
                if not text_content:
                    return self.create_text_message("text_content parameter is required for write operation")

                # Write content to S3
                self.s3_client.put_object(Bucket=bucket, Key=key, Body=text_content.encode("utf-8"))
                result = f"s3://{bucket}/{key}"

                # Generate presigned URL for the written object if requested
                if generate_presign_url:
                    result = self.s3_client.generate_presigned_url(
                        "get_object", Params={"Bucket": bucket, "Key": key}, ExpiresIn=presign_expiry
                    )

            else:  # read operation
                # Get object from S3
                response = self.s3_client.get_object(Bucket=bucket, Key=key)
                result = response["Body"].read().decode("utf-8")

                # Generate presigned URL if requested
                if generate_presign_url:
                    result = self.s3_client.generate_presigned_url(
                        "get_object", Params={"Bucket": bucket, "Key": key}, ExpiresIn=presign_expiry
                    )

            return self.create_text_message(text=result)

        except self.s3_client.exceptions.NoSuchBucket:
            return self.create_text_message(f"Bucket '{bucket}' does not exist")
        except self.s3_client.exceptions.NoSuchKey:
            return self.create_text_message(f"Object '{key}' does not exist in bucket '{bucket}'")
        except Exception as e:
            return self.create_text_message(f"Exception: {str(e)}")


================================================
FILE: builtin_tools/aws/tools/s3_operator.yaml
================================================
identity:
  name: s3_operator
  author: AWS
  label:
    en_US: AWS S3 Operator
    zh_Hans: AWS S3 读写器
    pt_BR: AWS S3 Operator
  icon: icon.svg
description:
  human:
    en_US: AWS S3 Writer and Reader
    zh_Hans: 读写S3 bucket中的文件
    pt_BR: AWS S3 Writer and Reader
  llm: AWS S3 Writer and Reader
parameters:
  - name: text_content
    type: string
    required: false
    label:
      en_US: The text to write
      zh_Hans: 待写入的文本
      pt_BR: The text to write
    human_description:
      en_US: The text to write
      zh_Hans: 待写入的文本
      pt_BR: The text to write
    llm_description: The text to write
    form: llm
  - name: s3_uri
    type: string
    required: true
    label:
      en_US: s3 uri
      zh_Hans: s3 uri
      pt_BR: s3 uri
    human_description:
      en_US: s3 uri
      zh_Hans: s3 uri
      pt_BR: s3 uri
    llm_description: s3 uri
    form: llm
  - name: aws_region
    type: string
    required: true
    label:
      en_US: region of bucket
      zh_Hans: bucket 所在的region
      pt_BR: region of bucket
    human_description:
      en_US: region of bucket
      zh_Hans: bucket 所在的region
      pt_BR: region of bucket
    llm_description: region of bucket
    form: form
  - name: operation_type
    type: select
    required: true
    label:
      en_US: operation type
      zh_Hans: 操作类型
      pt_BR: operation type
    human_description:
      en_US: operation type
      zh_Hans: 操作类型
      pt_BR: operation type
    default: read
    options:
      - value: read
        label:
          en_US: read
          zh_Hans: 读
      - value: write
        label:
          en_US: write
          zh_Hans: 写
    form: form
  - name: generate_presign_url
    type: boolean
    required: false
    label:
      en_US: Generate presigned URL
      zh_Hans: 生成预签名URL
    human_description:
      en_US: Whether to generate a presigned URL for the S3 object
      zh_Hans: 是否生成S3对象的预签名URL
    default: false
    form: form
  - name: presign_expiry
    type: number
    required: false
    label:
      en_US: Presigned URL expiration time
      zh_Hans: 预签名URL有效期
    human_description:
      en_US: Expiration time in seconds for the presigned URL
      zh_Hans: 预签名URL的有效期(秒)
    default: 3600
    form: form


================================================
FILE: builtin_tools/aws/tools/sagemaker_audio_to_text.py
================================================
import json
from typing import Any, Union
import boto3
import tempfile
import os
from urllib.parse import urlparse

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool


class WhisperTranscriptionTool(BuiltinTool):
    sagemaker_client: Any = None
    s3_client: Any = None
    sagemaker_endpoint: str = None

    def _get_s3_object_from_url(self, s3_url: str) -> tuple[str, str]:
        """从S3 URL解析出bucket和key"""
        parsed_url = urlparse(s3_url)
        bucket = parsed_url.netloc
        key = parsed_url.path.lstrip('/')
        return bucket, key

    def _download_from_s3(self, s3_url: str) -> str:
        """从S3下载文件到临时目录"""
        try:
            bucket, key = self._get_s3_object_from_url(s3_url)

            # 创建临时文件
            temp_file = tempfile.NamedTemporaryFile(delete=False)
            temp_path = temp_file.name
            temp_file.close()

            # 下载文件
            self.s3_client.download_file(bucket, key, temp_path)

            return temp_path
        except Exception as e:
            raise Exception(f"从S3下载文件失败: {str(e)}")

    def _invoke_sagemaker(self, audio_data: bytes, endpoint: str):
        try:
            response = self.sagemaker_client.invoke_endpoint(
                EndpointName=endpoint,
                ContentType='audio/x-audio',
                Body=audio_data
            )
            response_body = response['Body'].read().decode('utf8')
            return response_body
        except Exception as e:
            raise Exception(f"转录失败: {str(e)}")

    def _invoke(self,
                user_id: str,
                tool_parameters: dict[str, Any],
                ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        temp_file_path = None
        try:
            # 初始化 AWS 客户端
            if not self.sagemaker_client or not self.s3_client:
                aws_region = tool_parameters.get('aws_region')
                if aws_region:
                    self.sagemaker_client = boto3.client("sagemaker-runtime", region_name=aws_region)
                    self.s3_client = boto3.client('s3', region_name=aws_region)
                else:
                    self.sagemaker_client = boto3.client("sagemaker-runtime")
                    self.s3_client = boto3.client('s3')

            if not self.sagemaker_endpoint:
                self.sagemaker_endpoint = tool_parameters.get('sagemaker_endpoint')

            # 获取文件URL并下载
            file_url = tool_parameters.get('file_url')
            temp_file_path = self._download_from_s3(file_url)

            # 读取音频文件
            with open(temp_file_path, 'rb') as f:
                audio_data = f.read()

            # 调用 SageMaker 端点
            result = self._invoke_sagemaker(audio_data, self.sagemaker_endpoint)

            return self.create_text_message(text=result)

        except Exception as e:
            return self.create_text_message(f'Exception {str(e)}')
        finally:
            # 清理临时文件
            if temp_file_path and os.path.exists(temp_file_path):
                try:
                    os.unlink(temp_file_path)
                except:
                    pass

================================================
FILE: builtin_tools/aws/tools/sagemaker_audio_to_text.yaml
================================================
identity:
  name: whisper_transcription
  author: AWS
  label:
    en_US: Audio Transcription
    zh_Hans: 语音转文字
  icon: icon.svg
description:
  human:
    en_US: A tool to transcribe audio to text using Whisper model
    zh_Hans: 使用 Whisper 模型将语音转换为文字的工具
  llm: A tool that transcribes audio content to text using Whisper model
parameters:
  - name: sagemaker_endpoint
    type: string
    required: true
    label:
      en_US: SageMaker endpoint for Whisper model
      zh_Hans: Whisper模型的SageMaker端点
    human_description:
      en_US: SageMaker endpoint for Whisper model transcription
      zh_Hans: Whisper模型转录服务的SageMaker端点
    llm_description: SageMaker endpoint for Whisper model transcription
    form: llm
  - name: file_url
    type: string
    required: true
    label:
      en_US: video or audio file url for transcribe
      zh_Hans: 语音文件url
    human_description:
      en_US: audio file url for transcribe
      zh_Hans: 语音文件url
    llm_description: video or audio file url for transcribe
    form: llm
  - name: aws_region
    type: string
    required: false
    label:
      en_US: Region of SageMaker endpoint
      zh_Hans: SageMaker端点所在的region
    human_description:
      en_US: Region of SageMaker endpoint
      zh_Hans: SageMaker端点所在的region
    llm_description: Region of SageMaker endpoint
    form: llm

================================================
FILE: builtin_tools/aws/tools/sagemaker_chinese_toxicity_detector.py
================================================
import json
from typing import Any, Union

import boto3

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool

# Define label mappings
LABEL_MAPPING = {0: "SAFE", 1: "NO_SAFE"}


class ContentModerationTool(BuiltinTool):
    sagemaker_client: Any = None
    sagemaker_endpoint: str = None

    def _invoke_sagemaker(self, payload: dict, endpoint: str):
        response = self.sagemaker_client.invoke_endpoint(
            EndpointName=endpoint,
            Body=json.dumps(payload),
            ContentType="application/json",
        )
        # Parse response
        response_body = response["Body"].read().decode("utf8")

        json_obj = json.loads(response_body)

        # Handle nested JSON if present
        if isinstance(json_obj, dict) and "body" in json_obj:
            body_content = json.loads(json_obj["body"])
            prediction_result = body_content.get("prediction")
        else:
            prediction_result = json_obj.get("prediction")

        # Map labels and return
        result = LABEL_MAPPING.get(prediction_result, "NO_SAFE")  # If not found in mapping, default to NO_SAFE
        return result

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        try:
            if not self.sagemaker_client:
                aws_region = tool_parameters.get("aws_region")
                if aws_region:
                    self.sagemaker_client = boto3.client("sagemaker-runtime", region_name=aws_region)
                else:
                    self.sagemaker_client = boto3.client("sagemaker-runtime")

            if not self.sagemaker_endpoint:
                self.sagemaker_endpoint = tool_parameters.get("sagemaker_endpoint")

            content_text = tool_parameters.get("content_text")

            payload = {"text": content_text}

            result = self._invoke_sagemaker(payload, self.sagemaker_endpoint)

            return self.create_text_message(text=result)

        except Exception as e:
            return self.create_text_message(f"Exception {str(e)}")


================================================
FILE: builtin_tools/aws/tools/sagemaker_chinese_toxicity_detector.yaml
================================================
identity:
  name: chinese_toxicity_detector
  author: AWS
  label:
    en_US: Chinese Toxicity Detector
    zh_Hans: 中文有害内容检测
  icon: icon.svg
description:
  human:
    en_US: A tool to detect Chinese toxicity
    zh_Hans: 检测中文有害内容的工具
  llm: A tool that checks if Chinese content is safe for work
parameters:
  - name: sagemaker_endpoint
    type: string
    required: true
    label:
      en_US: sagemaker endpoint for moderation
      zh_Hans: 内容审核的SageMaker端点
    human_description:
      en_US: sagemaker endpoint for content moderation
      zh_Hans: 内容审核的SageMaker端点
    llm_description: sagemaker endpoint for content moderation
    form: form
  - name: content_text
    type: string
    required: true
    label:
      en_US: content text
      zh_Hans: 待审核文本
    human_description:
      en_US: text content to be moderated
      zh_Hans: 需要审核的文本内容
    llm_description: text content to be moderated
    form: llm
  - name: aws_region
    type: string
    required: false
    label:
      en_US: region of sagemaker endpoint
      zh_Hans: SageMaker 端点所在的region
    human_description:
      en_US: region of sagemaker endpoint
      zh_Hans: SageMaker 端点所在的region
    llm_description: region of sagemaker endpoint
    form: form


================================================
FILE: builtin_tools/aws/tools/sagemaker_text_rerank.py
================================================
import json
import operator
from typing import Any, Union

import boto3  # type: ignore

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool


class SageMakerReRankTool(BuiltinTool):
    sagemaker_client: Any = None
    sagemaker_endpoint: str = None

    def _sagemaker_rerank(self, query_input: str, docs: list[str], rerank_endpoint: str):
        inputs = [query_input] * len(docs)
        response_model = self.sagemaker_client.invoke_endpoint(
            EndpointName=rerank_endpoint,
            Body=json.dumps({"inputs": inputs, "docs": docs}),
            ContentType="application/json",
        )
        json_str = response_model["Body"].read().decode("utf8")
        json_obj = json.loads(json_str)
        scores = json_obj["scores"]
        return scores if isinstance(scores, list) else [scores]

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        line = 0
        try:
            if not self.sagemaker_client:
                aws_region = tool_parameters.get("aws_region")
                if aws_region:
                    self.sagemaker_client = boto3.client("sagemaker-runtime", region_name=aws_region)
                else:
                    self.sagemaker_client = boto3.client("sagemaker-runtime")

            line = 1
            if not self.sagemaker_endpoint:
                self.sagemaker_endpoint = tool_parameters.get("sagemaker_endpoint")

            line = 2
            topk = tool_parameters.get("topk", 5)

            line = 3
            query = tool_parameters.get("query", "")
            if not query:
                return self.create_text_message("Please input query")

            line = 4
            candidate_texts = tool_parameters.get("candidate_texts")
            if not candidate_texts:
                return self.create_text_message("Please input candidate_texts")

            line = 5
            candidate_docs = json.loads(candidate_texts)
            docs = [item.get("content") for item in candidate_docs]

            line = 6
            scores = self._sagemaker_rerank(query_input=query, docs=docs, rerank_endpoint=self.sagemaker_endpoint)

            line = 7
            for idx in range(len(candidate_docs)):
                candidate_docs[idx]["score"] = scores[idx]

            line = 8
            sorted_candidate_docs = sorted(candidate_docs, key=operator.itemgetter("score"), reverse=True)

            line = 9
            return [self.create_json_message(res) for res in sorted_candidate_docs[:topk]]

        except Exception as e:
            return self.create_text_message(f"Exception {str(e)}, line : {line}")


================================================
FILE: builtin_tools/aws/tools/sagemaker_text_rerank.yaml
================================================
identity:
  name: sagemaker_text_rerank
  author: AWS
  label:
    en_US: SagemakerRerank
    zh_Hans: Sagemaker重排序
    pt_BR: SagemakerRerank
  icon: icon.svg
description:
  human:
    en_US: A tool for performing text similarity ranking. You can find deploy notebook on Github Repo - https://github.com/aws-samples/dify-aws-tool
    zh_Hans: Sagemaker重排序工具, 请参考 Github Repo - https://github.com/aws-samples/dify-aws-tool上的部署脚本
    pt_BR: A tool for performing text similarity ranking.
  llm: A tool for performing text similarity ranking. You can find deploy notebook on Github Repo - https://github.com/aws-samples/dify-aws-tool
parameters:
  - name: sagemaker_endpoint
    type: string
    required: true
    label:
      en_US: sagemaker endpoint for reranking
      zh_Hans: 重排序的SageMaker 端点
      pt_BR: sagemaker endpoint for reranking
    human_description:
      en_US: sagemaker endpoint for reranking
      zh_Hans: 重排序的SageMaker 端点
      pt_BR: sagemaker endpoint for reranking
    llm_description: sagemaker endpoint for reranking
    form: form
  - name: query
    type: string
    required: true
    label:
      en_US: Query string
      zh_Hans: 查询语句
      pt_BR: Query string
    human_description:
      en_US: key words for searching
      zh_Hans: 查询关键词
      pt_BR: key words for searching
    llm_description: key words for searching
    form: llm
  - name: candidate_texts
    type: string
    required: true
    label:
      en_US: text candidates
      zh_Hans: 候选文本
      pt_BR: text candidates
    human_description:
      en_US: searched candidates by query
      zh_Hans: 查询文本搜到候选文本
      pt_BR: searched candidates by query
    llm_description: searched candidates by query
    form: llm
  - name: topk
    type: number
    required: false
    form: form
    label:
      en_US: Limit for results count
      zh_Hans: 返回个数限制
      pt_BR: Limit for results count
    human_description:
      en_US: Limit for results count
      zh_Hans: 返回个数限制
      pt_BR: Limit for results count
    min: 1
    max: 10
    default: 5
  - name: aws_region
    type: string
    required: false
    label:
      en_US: region of sagemaker endpoint
      zh_Hans: SageMaker 端点所在的region
      pt_BR: region of sagemaker endpoint
    human_description:
      en_US: region of sagemaker endpoint
      zh_Hans: SageMaker 端点所在的region
      pt_BR: region of sagemaker endpoint
    llm_description: region of sagemaker endpoint
    form: form


================================================
FILE: builtin_tools/aws/tools/sagemaker_tts.py
================================================
import json
from enum import Enum
from typing import Any, Optional, Union

import boto3  # type: ignore

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool


class TTSModelType(Enum):
    PresetVoice = "PresetVoice"
    CloneVoice = "CloneVoice"
    CloneVoice_CrossLingual = "CloneVoice_CrossLingual"
    InstructVoice = "InstructVoice"


class SageMakerTTSTool(BuiltinTool):
    sagemaker_client: Any = None
    sagemaker_endpoint: str | None = None
    s3_client: Any = None
    comprehend_client: Any = None

    def _detect_lang_code(self, content: str, map_dict: Optional[dict] = None):
        map_dict = {"zh": "<|zh|>", "en": "<|en|>", "ja": "<|jp|>", "zh-TW": "<|yue|>", "ko": "<|ko|>"}

        response = self.comprehend_client.detect_dominant_language(Text=content)
        language_code = response["Languages"][0]["LanguageCode"]
        return map_dict.get(language_code, "<|zh|>")

    def _build_tts_payload(
        self,
        model_type: str,
        content_text: str,
        model_role: str,
        prompt_text: str,
        prompt_audio: str,
        instruct_text: str,
    ):
        if model_type == TTSModelType.PresetVoice.value and model_role:
            return {"tts_text": content_text, "role": model_role}
        if model_type == TTSModelType.CloneVoice.value and prompt_text and prompt_audio:
            return {"tts_text": content_text, "prompt_text": prompt_text, "prompt_audio": prompt_audio}
        if model_type == TTSModelType.CloneVoice_CrossLingual.value and prompt_audio:
            lang_tag = self._detect_lang_code(content_text)
            return {"tts_text": f"{content_text}", "prompt_audio": prompt_audio, "lang_tag": lang_tag}
        if model_type == TTSModelType.InstructVoice.value and instruct_text and model_role:
            return {"tts_text": content_text, "role": model_role, "instruct_text": instruct_text}

        raise RuntimeError(f"Invalid params for {model_type}")

    def _invoke_sagemaker(self, payload: dict, endpoint: str):
        response_model = self.sagemaker_client.invoke_endpoint(
            EndpointName=endpoint,
            Body=json.dumps(payload),
            ContentType="application/json",
        )
        json_str = response_model["Body"].read().decode("utf8")
        json_obj = json.loads(json_str)
        return json_obj

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        try:
            if not self.sagemaker_client:
                aws_region = tool_parameters.get("aws_region")
                if aws_region:
                    self.sagemaker_client = boto3.client("sagemaker-runtime", region_name=aws_region)
                    self.s3_client = boto3.client("s3", region_name=aws_region)
                    self.comprehend_client = boto3.client("comprehend", region_name=aws_region)
                else:
                    self.sagemaker_client = boto3.client("sagemaker-runtime")
                    self.s3_client = boto3.client("s3")
                    self.comprehend_client = boto3.client("comprehend")

            if not self.sagemaker_endpoint:
                self.sagemaker_endpoint = tool_parameters.get("sagemaker_endpoint")

            tts_text = tool_parameters.get("tts_text")
            tts_infer_type = tool_parameters.get("tts_infer_type")

            voice = tool_parameters.get("voice")
            mock_voice_audio = tool_parameters.get("mock_voice_audio")
            mock_voice_text = tool_parameters.get("mock_voice_text")
            voice_instruct_prompt = tool_parameters.get("voice_instruct_prompt")
            payload = self._build_tts_payload(
                tts_infer_type, tts_text, voice, mock_voice_text, mock_voice_audio, voice_instruct_prompt
            )

            result = self._invoke_sagemaker(payload, self.sagemaker_endpoint)

            return self.create_text_message(text=result["s3_presign_url"])

        except Exception as e:
            return self.create_text_message(f"Exception {str(e)}")


================================================
FILE: builtin_tools/aws/tools/sagemaker_tts.yaml
================================================
identity:
  name: sagemaker_tts
  author: AWS
  label:
    en_US: SagemakerTTS
    zh_Hans: Sagemaker语音合成
    pt_BR: SagemakerTTS
  icon: icon.svg
description:
  human:
    en_US: A tool for Speech synthesis - https://github.com/aws-samples/dify-aws-tool
    zh_Hans: Sagemaker语音合成工具, 请参考 Github Repo - https://github.com/aws-samples/dify-aws-tool上的部署脚本
    pt_BR: A tool for Speech synthesis.
  llm: A tool for Speech synthesis. You can find deploy notebook on Github Repo - https://github.com/aws-samples/dify-aws-tool
parameters:
  - name: sagemaker_endpoint
    type: string
    required: true
    label:
      en_US: sagemaker endpoint for tts
      zh_Hans: 语音生成的SageMaker端点
      pt_BR: sagemaker endpoint for tts
    human_description:
      en_US: sagemaker endpoint for tts
      zh_Hans: 语音生成的SageMaker端点
      pt_BR: sagemaker endpoint for tts
    llm_description: sagemaker endpoint for tts
    form: form
  - name: tts_text
    type: string
    required: true
    label:
      en_US: tts text
      zh_Hans: 语音合成原文
      pt_BR: tts text
    human_description:
      en_US: tts text
      zh_Hans: 语音合成原文
      pt_BR: tts text
    llm_description: tts text
    form: llm
  - name: tts_infer_type
    type: select
    required: false
    label:
      en_US: tts infer type
      zh_Hans: 合成方式
      pt_BR: tts infer type
    human_description:
      en_US: tts infer type
      zh_Hans: 合成方式
      pt_BR: tts infer type
    llm_description: tts infer type
    options:
      - value: PresetVoice
        label:
          en_US: preset voice
          zh_Hans: 预置音色
      - value: CloneVoice
        label:
          en_US: clone voice
          zh_Hans: 克隆音色
      - value: CloneVoice_CrossLingual
        label:
          en_US: clone crossLingual voice
          zh_Hans: 克隆音色(跨语言)
      - value: InstructVoice
        label:
          en_US: instruct voice
          zh_Hans: 指令音色
    form: form
  - name: voice
    type: select
    required: false
    label:
      en_US: preset voice
      zh_Hans: 预置音色
      pt_BR: preset voice
    human_description:
      en_US: preset voice
      zh_Hans: 预置音色
      pt_BR: preset voice
    llm_description: preset voice
    options:
      - value: 中文男
        label:
          en_US: zh-cn male
          zh_Hans: 中文男
      - value: 中文女
        label:
          en_US: zh-cn female
          zh_Hans: 中文女
      - value: 粤语女
        label:
          en_US: zh-TW female
          zh_Hans: 粤语女
    form: form
  - name: mock_voice_audio
    type: string
    required: false
    label:
      en_US: clone voice link
      zh_Hans: 克隆音频链接
      pt_BR: clone voice link
    human_description:
      en_US: clone voice link
      zh_Hans: 克隆音频链接
      pt_BR: clone voice link
    llm_description: clone voice link
    form: llm
  - name: mock_voice_text
    type: string
    required: false
    label:
      en_US: text of clone voice
      zh_Hans: 克隆音频对应文本
      pt_BR: text of clone voice
    human_description:
      en_US: text of clone voice
      zh_Hans: 克隆音频对应文本
      pt_BR: text of clone voice
    llm_description: text of clone voice
    form: llm
  - name: voice_instruct_prompt
    type: string
    required: false
    label:
      en_US: instruct prompt for voice
      zh_Hans: 音色指令文本
      pt_BR: instruct prompt for voice
    human_description:
      en_US: instruct prompt for voice
      zh_Hans: 音色指令文本
      pt_BR: instruct prompt for voice
    llm_description: instruct prompt for voice
    form: llm
  - name: aws_region
    type: string
    required: false
    label:
      en_US: region of sagemaker endpoint
      zh_Hans: SageMaker 端点所在的region
      pt_BR: region of sagemaker endpoint
    human_description:
      en_US: region of sagemaker endpoint
      zh_Hans: SageMaker 端点所在的region
      pt_BR: region of sagemaker endpoint
    llm_description: region of sagemaker endpoint
    form: form


================================================
FILE: builtin_tools/aws/tools/transcribe_asr.py
================================================
import json
import logging
import os
import re
import time
import uuid
from typing import Any, Union
from urllib.parse import urlparse

import boto3
import requests
from botocore.exceptions import ClientError
from requests.exceptions import RequestException

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


LanguageCodeOptions = [
    "af-ZA",
    "ar-AE",
    "ar-SA",
    "da-DK",
    "de-CH",
    "de-DE",
    "en-AB",
    "en-AU",
    "en-GB",
    "en-IE",
    "en-IN",
    "en-US",
    "en-WL",
    "es-ES",
    "es-US",
    "fa-IR",
    "fr-CA",
    "fr-FR",
    "he-IL",
    "hi-IN",
    "id-ID",
    "it-IT",
    "ja-JP",
    "ko-KR",
    "ms-MY",
    "nl-NL",
    "pt-BR",
    "pt-PT",
    "ru-RU",
    "ta-IN",
    "te-IN",
    "tr-TR",
    "zh-CN",
    "zh-TW",
    "th-TH",
    "en-ZA",
    "en-NZ",
    "vi-VN",
    "sv-SE",
    "ab-GE",
    "ast-ES",
    "az-AZ",
    "ba-RU",
    "be-BY",
    "bg-BG",
    "bn-IN",
    "bs-BA",
    "ca-ES",
    "ckb-IQ",
    "ckb-IR",
    "cs-CZ",
    "cy-WL",
    "el-GR",
    "et-ET",
    "eu-ES",
    "fi-FI",
    "gl-ES",
    "gu-IN",
    "ha-NG",
    "hr-HR",
    "hu-HU",
    "hy-AM",
    "is-IS",
    "ka-GE",
    "kab-DZ",
    "kk-KZ",
    "kn-IN",
    "ky-KG",
    "lg-IN",
    "lt-LT",
    "lv-LV",
    "mhr-RU",
    "mi-NZ",
    "mk-MK",
    "ml-IN",
    "mn-MN",
    "mr-IN",
    "mt-MT",
    "no-NO",
    "or-IN",
    "pa-IN",
    "pl-PL",
    "ps-AF",
    "ro-RO",
    "rw-RW",
    "si-LK",
    "sk-SK",
    "sl-SI",
    "so-SO",
    "sr-RS",
    "su-ID",
    "sw-BI",
    "sw-KE",
    "sw-RW",
    "sw-TZ",
    "sw-UG",
    "tl-PH",
    "tt-RU",
    "ug-CN",
    "uk-UA",
    "uz-UZ",
    "wo-SN",
    "zu-ZA",
]

MediaFormat = ["mp3", "mp4", "wav", "flac", "ogg", "amr", "webm", "m4a"]


def is_url(text):
    if not text:
        return False
    text = text.strip()
    # Regular expression pattern for URL validation
    pattern = re.compile(
        r"^"  # Start of the string
        r"(?:http|https)://"  # Protocol (http or https)
        r"(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|"  # Domain
        r"localhost|"  # localhost
        r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"  # IP address
        r"(?::\d+)?"  # Optional port
        r"(?:/?|[/?]\S+)"  # Path
        r"$",  # End of the string
        re.IGNORECASE,
    )
    return bool(pattern.match(text))


def upload_file_from_url_to_s3(s3_client, url, bucket_name, s3_key=None, max_retries=3):
    """
    Upload a file from a URL to an S3 bucket with retries and better error handling.

    Parameters:
    - s3_client
    - url (str): The URL of the file to upload
    - bucket_name (str): The name of the S3 bucket
    - s3_key (str): The desired key (path) in S3. If None, will use the filename from URL
    - max_retries (int): Maximum number of retry attempts

    Returns:
    - tuple: (bool, str) - (Success status, Message)
    """

    # Validate inputs
    if not url or not bucket_name:
        return False, "URL and bucket name are required"

    retry_count = 0
    while retry_count < max_retries:
        try:
            # Download the file from URL
            response = requests.get(url, stream=True, timeout=30)
            response.raise_for_status()

            # If s3_key is not provided, try to get filename from URL
            if not s3_key:
                parsed_url = urlparse(url)
                filename = os.path.basename(parsed_url.path.split("/file-preview")[0])
                s3_key = "transcribe-files/" + filename

            # Upload the file to S3
            s3_client.upload_fileobj(
                response.raw,
                bucket_name,
                s3_key,
                ExtraArgs={
                    "ContentType": response.headers.get("content-type"),
                    "ACL": "private",  # Ensure the uploaded file is private
                },
            )

            return f"s3://{bucket_name}/{s3_key}", f"Successfully uploaded file to s3://{bucket_name}/{s3_key}"

        except RequestException as e:
            retry_count += 1
            if retry_count == max_retries:
                return None, f"Failed to download file from URL after {max_retries} attempts: {str(e)}"
            continue

        except ClientError as e:
            return None, f"AWS S3 error: {str(e)}"

        except Exception as e:
            return None, f"Unexpected error: {str(e)}"

    return None, "Maximum retries exceeded"


class TranscribeTool(BuiltinTool):
    s3_client: Any = None
    transcribe_client: Any = None

    """
    Note that you must include one of LanguageCode, IdentifyLanguage,
    or IdentifyMultipleLanguages in your request. 
    If you include more than one of these parameters, your transcription job fails.
    """

    def _transcribe_audio(self, audio_file_uri, file_type, **extra_args):
        uuid_str = str(uuid.uuid4())
        job_name = f"{int(time.time())}-{uuid_str}"
        try:
            # Start transcription job
            response = self.transcribe_client.start_transcription_job(
                TranscriptionJobName=job_name, Media={"MediaFileUri": audio_file_uri}, **extra_args
            )

            # Wait for the job to complete
            while True:
                status = self.transcribe_client.get_transcription_job(TranscriptionJobName=job_name)
                if status["TranscriptionJob"]["TranscriptionJobStatus"] in ["COMPLETED", "FAILED"]:
                    break
                time.sleep(5)

            if status["TranscriptionJob"]["TranscriptionJobStatus"] == "COMPLETED":
                return status["TranscriptionJob"]["Transcript"]["TranscriptFileUri"], None
            else:
                return None, f"Error: TranscriptionJobStatus:{status['TranscriptionJob']['TranscriptionJobStatus']} "

        except Exception as e:
            return None, f"Error: {str(e)}"

    def _download_and_read_transcript(self, transcript_file_uri: str, max_retries: int = 3) -> tuple[str, str]:
        """
        Download and read the transcript file from the given URI.

        Parameters:
        - transcript_file_uri (str): The URI of the transcript file
        - max_retries (int): Maximum number of retry attempts

        Returns:
        - tuple: (text, error) - (Transcribed text if successful, error message if failed)
        """
        retry_count = 0
        while retry_count < max_retries:
            try:
                # Download the transcript file
                response = requests.get(transcript_file_uri, timeout=30)
                response.raise_for_status()

                # Parse the JSON content
                transcript_data = response.json()

                # Check if speaker labels are present and enabled
                has_speaker_labels = (
                    "results" in transcript_data
                    and "speaker_labels" in transcript_data["results"]
                    and "segments" in transcript_data["results"]["speaker_labels"]
                )

                if has_speaker_labels:
                    # Get speaker segments
                    segments = transcript_data["results"]["speaker_labels"]["segments"]
                    items = transcript_data["results"]["items"]

                    # Create a mapping of start_time -> speaker_label
                    time_to_speaker = {}
                    for segment in segments:
                        speaker_label = segment["speaker_label"]
                        for item in segment["items"]:
                            time_to_speaker[item["start_time"]] = speaker_label

                    # Build transcript with speaker labels
                    current_speaker = None
                    transcript_parts = []

                    for item in items:
                        # Skip non-pronunciation items (like punctuation)
                        if item["type"] == "punctuation":
                            transcript_parts.append(item["alternatives"][0]["content"])
                            continue

                        start_time = item["start_time"]
                        speaker = time_to_speaker.get(start_time)

                        if speaker != current_speaker:
                            current_speaker = speaker
                            transcript_parts.append(f"\n[{speaker}]: ")

                        transcript_parts.append(item["alternatives"][0]["content"])

                    return " ".join(transcript_parts).strip(), None
                else:
                    # Extract the transcription text
                    # The transcript text is typically in the 'results' -> 'transcripts' array
                    if "results" in transcript_data and "transcripts" in transcript_data["results"]:
                        transcripts = transcript_data["results"]["transcripts"]
                        if transcripts:
                            # Combine all transcript segments
                            full_text = " ".join(t.get("transcript", "") for t in transcripts)
                            return full_text, None

                return None, "No transcripts found in the response"

            except requests.exceptions.RequestException as e:
                retry_count += 1
                if retry_count == max_retries:
                    return None, f"Failed to download transcript file after {max_retries} attempts: {str(e)}"
                continue

            except json.JSONDecodeError as e:
                return None, f"Failed to parse transcript JSON: {str(e)}"

            except Exception as e:
                return None, f"Unexpected error while processing transcript: {str(e)}"

        return None, "Maximum retries exceeded"

    def _invoke(
        self,
        user_id: str,
        tool_parameters: dict[str, Any],
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        """
        invoke tools
        """
        try:
            if not self.transcribe_client:
                aws_region = tool_parameters.get("aws_region")
                if aws_region:
                    self.transcribe_client = boto3.client("transcribe", region_name=aws_region)
                    self.s3_client = boto3.client("s3", region_name=aws_region)
                else:
                    self.transcribe_client = boto3.client("transcribe")
                    self.s3_client = boto3.client("s3")

            file_url = tool_parameters.get("file_url")
            file_type = tool_parameters.get("file_type")
            language_code = tool_parameters.get("language_code")
            identify_language = tool_parameters.get("identify_language", True)
            identify_multiple_languages = tool_parameters.get("identify_multiple_languages", False)
            language_options_str = tool_parameters.get("language_options")
            s3_bucket_name = tool_parameters.get("s3_bucket_name")
            ShowSpeakerLabels = tool_parameters.get("ShowSpeakerLabels", True)
            MaxSpeakerLabels = tool_parameters.get("MaxSpeakerLabels", 2)

            # Check the input params
            if not s3_bucket_name:
                return self.create_text_message(text="s3_bucket_name is required")
            language_options = None
            if language_options_str:
                language_options = language_options_str.split("|")
                for lang in language_options:
                    if lang not in LanguageCodeOptions:
                        return self.create_text_message(
                            text=f"{lang} is not supported, should be one of {LanguageCodeOptions}"
                        )
            if language_code and language_code not in LanguageCodeOptions:
                err_msg = f"language_code:{language_code} is not supported, should be one of {LanguageCodeOptions}"
                return self.create_text_message(text=err_msg)

            err_msg = f"identify_language:{identify_language}, \
                identify_multiple_languages:{identify_multiple_languages}, \
                Note that you must include one of LanguageCode, IdentifyLanguage, \
                or IdentifyMultipleLanguages in your request. \
                If you include more than one of these parameters, \
                your transcription job fails."
            if not language_code:
                if identify_language and identify_multiple_languages:
                    return self.create_text_message(text=err_msg)
            else:
                if identify_language or identify_multiple_languages:
                    return self.create_text_message(text=err_msg)

            extra_args = {
                "IdentifyLanguage": identify_language,
                "IdentifyMultipleLanguages": identify_multiple_languages,
            }
            if language_code:
                extra_args["LanguageCode"] = language_code
            if language_options:
                extra_args["LanguageOptions"] = language_options
            if ShowSpeakerLabels:
                extra_args["Settings"] = {"ShowSpeakerLabels": ShowSpeakerLabels, "MaxSpeakerLabels": MaxSpeakerLabels}

            # upload to s3 bucket
            s3_path_result, error = upload_file_from_url_to_s3(self.s3_client, url=file_url, bucket_name=s3_bucket_name)
            if not s3_path_result:
                return self.create_text_message(text=error)

            transcript_file_uri, error = self._transcribe_audio(
                audio_file_uri=s3_path_result,
                file_type=file_type,
                **extra_args,
            )
            if not transcript_file_uri:
                return self.create_text_message(text=error)

            # Download and read the transcript
            transcript_text, error = self._download_and_read_transcript(transcript_file_uri)
            if not transcript_text:
                return self.create_text_message(text=error)

            return self.create_text_message(text=transcript_text)

        except Exception as e:
            return self.create_text_message(f"Exception {str(e)}")


================================================
FILE: builtin_tools/aws/tools/transcribe_asr.yaml
================================================
identity:
  name: transcribe_asr
  author: AWS
  label:
    en_US: TranscribeASR
    zh_Hans: Transcribe语音识别转录
    pt_BR: TranscribeASR
  icon: icon.svg
description:
  human:
    en_US: A tool for ASR (Automatic Speech Recognition) - https://github.com/aws-samples/dify-aws-tool
    zh_Hans: AWS 语音识别转录服务, 请参考 https://aws.amazon.com/cn/pm/transcribe/#Learn_More_About_Amazon_Transcribe
    pt_BR: A tool for ASR (Automatic Speech Recognition).
  llm: A tool for ASR (Automatic Speech Recognition).
parameters:
  - name: file_url
    type: string
    required: true
    label:
      en_US: video or audio file url for transcribe
      zh_Hans: 语音或者视频文件url
      pt_BR: video or audio file url for transcribe
    human_description:
      en_US: video or audio file url for transcribe
      zh_Hans: 语音或者视频文件url
      pt_BR: video or audio file url for transcribe
    llm_description: video or audio file url for transcribe
    form: llm
  - name: language_code
    type: string
    required: false
    label:
      en_US: Language Code
      zh_Hans: 语言编码
      pt_BR: Language Code
    human_description:
      en_US: The language code used to create your transcription job.  refer to :https://docs.aws.amazon.com/transcribe/latest/dg/supported-languages.html
      zh_Hans: 语言编码,例如zh-CN, en-US 可参考 https://docs.aws.amazon.com/transcribe/latest/dg/supported-languages.html
      pt_BR: The language code used to create your transcription job.  refer to :https://docs.aws.amazon.com/transcribe/latest/dg/supported-languages.html
    llm_description: The language code used to create your transcription job.
    form: llm
  - name: identify_language
    type: boolean
    default: true
    required: false
    label:
      en_US: Automactically Identify Language
      zh_Hans: 自动识别语言
      pt_BR: Automactically Identify Language
    human_description:
      en_US: Automactically Identify Language
      zh_Hans: 自动识别语言
      pt_BR: Automactically Identify Language
    llm_description: Enable Automactically Identify Language
    form: form
  - name: identify_multiple_languages
    type: boolean
    required: false
    label:
      en_US: Automactically Identify Multiple Languages
      zh_Hans: 自动识别多种语言
      pt_BR: Automactically Identify Multiple Languages
    human_description:
      en_US: Automactically Identify Multiple Languages
      zh_Hans: 自动识别多种语言
      pt_BR: Automactically Identify Multiple Languages
    llm_description: Enable Automactically Identify Multiple Languages
    form: form
  - name: language_options
    type: string
    required: false
    label:
      en_US: Language Options
      zh_Hans: 语言种类选项
      pt_BR: Language Options
    human_description:
      en_US: Seperated by |, e.g:zh-CN|en-US, You can specify two or more language codes that represent the languages you think may be present in your media
      zh_Hans: 您可以指定两个或更多的语言代码来表示您认为可能出现在媒体中的语言。用|分隔,如 zh-CN|en-US
      pt_BR: Seperated by |, e.g:zh-CN|en-US, You can specify two or more language codes that represent the languages you think may be present in your media
    llm_description: Seperated by |, e.g:zh-CN|en-US, You can specify two or more language codes that represent the languages you think may be present in your media
    form: llm
  - name: s3_bucket_name
    type: string
    required: true
    label:
      en_US: s3 bucket name
      zh_Hans: s3 存储桶名称
      pt_BR: s3 bucket name
    human_description:
      en_US: s3 bucket name to store transcribe files  (don't add prefix s3://)
      zh_Hans: s3 存储桶名称,用于存储转录文件  (不需要前缀 s3://)
      pt_BR: s3 bucket name to store transcribe files  (don't add prefix s3://)
    llm_description: s3 bucket name to store transcribe files
    form: form
  - name: ShowSpeakerLabels
    type: boolean
    required: true
    default: true
    label:
      en_US: ShowSpeakerLabels
      zh_Hans: 显示说话人标签
      pt_BR: ShowSpeakerLabels
    human_description:
      en_US: Enables speaker partitioning (diarization) in your transcription output
      zh_Hans: 在转录输出中启用说话人分区(说话人分离)
      pt_BR: Enables speaker partitioning (diarization) in your transcription output
    llm_description: Enables speaker partitioning (diarization) in your transcription output
    form: form
  - name: MaxSpeakerLabels
    type: number
    required: true
    default: 2
    label:
      en_US: MaxSpeakerLabels
      zh_Hans: 说话人标签数量
      pt_BR: MaxSpeakerLabels
    human_description:
      en_US: Specify the maximum number of speakers you want to partition in your media
      zh_Hans: 指定您希望在媒体中划分的最多演讲者数量。
      pt_BR: Specify the maximum number of speakers you want to partition in your media
    llm_description: Specify the maximum number of speakers you want to partition in your media
    form: form
  - name: aws_region
    type: string
    required: false
    label:
      en_US: AWS Region
      zh_Hans: AWS 区域
    human_description:
      en_US: Please enter the AWS region for the transcribe service, for example 'us-east-1'.
      zh_Hans: 请输入Transcribe的 AWS 区域,例如 'us-east-1'。
    llm_description: Please enter the AWS region for the transcribe service, for example 'us-east-1'.
    form: form


================================================
FILE: dify.yaml
================================================
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: VPC settings
        Parameters:
          - IPv4CIDR
    ParameterLabels:
      IPv4CIDR:
        default: The Prefix of IPv4 CIDR
Parameters:
  IPv4CIDR:
    Type: String
    Default: "10.1"
    AllowedPattern: ^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
    Description: The subnet CIDR prefix, such as 10.1, defaults to a subnet mask of /16.
Resources:
  VPC:
    Type: AWS::CloudFormation::Stack
    Properties:
      Parameters:
        IPv4CIDR:
          Ref: IPv4CIDR
      TemplateURL: https://aws-gcr-solutions.s3.amazonaws.com/WCH-TEST/trackingemailengagement/template/ThreeLayerSubnets.template.json
    Metadata:
      aws:cdk:path: DifyOnAws/VPC
  PublicSecurityGroupfrom000008081FBE316:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      CidrIp: 0.0.0.0/0
      Description: from 0.0.0.0/0:80
      FromPort: 80
      GroupId:
        Fn::GetAtt:
          - VPC
          - Outputs.PublicSecurityGroupId
      IpProtocol: tcp
      ToPort: 80
    Metadata:
      aws:cdk:path: DifyOnAws/PublicSecurityGroup/from 0.0.0.0_0:80
  SageMakerNotebookIAMRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: 
                - sagemaker.amazonaws.com
            Action: 
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSageMakerFullAccess
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
      Policies:
        - PolicyName: S3FullAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: 's3:*'
                Resource: '*'
  IamInstanceProfileRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/AmazonSSMManagedInstanceCore
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/AmazonSageMakerFullAccess
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/ComprehendFullAccess
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/AmazonBedrockFullAccess
    Metadata:
      aws:cdk:path: DifyOnAws/IamInstanceProfileRole/Resource
  IamInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - Ref: IamInstanceProfileRole
    Metadata:
      aws:cdk:path: DifyOnAws/IamInstanceProfile
  InstallationInstance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile:
        Fn::Select:
          - 1
          - Fn::Split:
              - /
              - Fn::GetAtt:
                  - IamInstanceProfile
                  - Arn
      ImageId: "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-arm64}}"
      InstanceType: c7g.xlarge
      SecurityGroupIds:
        - Fn::GetAtt:
            - VPC
            - Outputs.PublicSecurityGroupId
      SubnetId:
        Fn::Select:
          - 0
          - Fn::Split:
              - ","
              - Fn::GetAtt:
                  - VPC
                  - Outputs.PublicSubnetIds
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: 50
            VolumeType: gp3
      UserData:
        Fn::Base64: |-
          #!/bin/bash

           yum install git docker -y && systemctl start docker && systemctl enable docker && curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose && git clone --depth 1 -b v0.15.0 https://github.com/langgenius/dify.git && cd dify/docker && docker-compose up -d
      Tags:
        - Key: Name
          Value: dify-server
    DependsOn:
      - IamInstanceProfile
    Metadata:
      aws:cdk:path: DifyOnAws/InstallationInstance
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/02Puw7CMAxFv4U9NSUs7B1QJ6ryASikLnIfceUkIFT13+lDlZiufM+RZWs4nS+QHszHJ7Zqk46eMN6Dsa3KalcYMT0GFDXzx2g7jlXN0ptA7GAWNhOthnGZ0Eah8L0KxyF3L0HvlzW588E4i5Mi08NYcodLveeOC+GaOpwmVaLnKHaltxiGGFb/r83YVbRcMSnHFULjj2+tIZ1faTxRItEF6hHKLX9WWVqb5wAAAA==
    Metadata:
      aws:cdk:path: DifyOnAws/CDKMetadata/Default
    Condition: CDKMetadataAvailable
Outputs:
  Host:
    Description: Host
    Value:
      Fn::Join:
        - ""
        - - http://
          - Fn::GetAtt:
              - InstallationInstance
              - PublicIp
          - :80
Conditions:
  CDKMetadataAvailable:
    Fn::Or:
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - af-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ca-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-northwest-1
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-2
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-3
          - Fn::Equals:
              - Ref: AWS::Region
              - il-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - me-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - me-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - sa-east-1
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-2
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-2


================================================
FILE: model_provider/sagemaker/__init__.py
================================================


================================================
FILE: model_provider/sagemaker/llm/__init__.py
================================================


================================================
FILE: model_provider/sagemaker/llm/llm.py
================================================
import json
import logging
import re
from collections.abc import Generator, Iterator
from typing import Any, Optional, Union, cast

import boto3

from core.model_runtime.entities.llm_entities import LLMMode, LLMResult, LLMResultChunk, LLMResultChunkDelta
from core.model_runtime.entities.message_entities import (
    AssistantPromptMessage,
    ImagePromptMessageContent,
    PromptMessage,
    PromptMessageContent,
    PromptMessageContentType,
    PromptMessageTool,
    SystemPromptMessage,
    ToolPromptMessage,
    UserPromptMessage,
)
from core.model_runtime.entities.model_entities import (
    AIModelEntity,
    FetchFrom,
    I18nObject,
    ModelFeature,
    ModelPropertyKey,
    ModelType,
    ParameterRule,
    ParameterType,
)
from core.model_runtime.errors.invoke import (
    InvokeAuthorizationError,
    InvokeBadRequestError,
    InvokeConnectionError,
    InvokeError,
    InvokeRateLimitError,
    InvokeServerUnavailableError,
)
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel

logger = logging.getLogger(__name__)


def inference(predictor, messages: list[dict[str, Any]], params: dict[str, Any], stop: list, stream=False):
    """
    params:
    predictor : Sagemaker Predictor
    messages (List[Dict[str,Any]]): message list。
                messages = [
                {"role": "system", "content":"please answer in Chinese"},
                {"role": "user", "content": "who are you? what are you doing?"},
            ]
    params (Dict[str,Any]): model parameters for LLM。
    stream (bool): False by default。

    response:
    result of inference if stream is False
    Iterator of Chunks if stream is True
    """
    payload = {
        "model": params.get("model_name"),
        "stop": stop,
        "messages": messages,
        "stream": stream,
        "max_tokens": params.get("max_new_tokens", params.get("max_tokens", 2048)),
        "temperature": params.get("temperature", 0.1),
        "top_p": params.get("top_p", 0.9),
    }

    if not stream:
        response = predictor.predict(payload)
        return response
    else:
        response_stream = predictor.predict_stream(payload)
        return response_stream


class SageMakerLargeLanguageModel(LargeLanguageModel):
    """
    Model class for Cohere large language model.
    """

    sagemaker_session: Any = None
    predictor: Any = None
    sagemaker_endpoint: str = None

    def _handle_chat_generate_response(
        self,
        model: str,
        credentials: dict,
        prompt_messages: list[PromptMessage],
        tools: list[PromptMessageTool],
        resp: bytes,
    ) -> LLMResult:
        """
        handle normal chat generate response
        """
        resp_obj = json.loads(resp.decode("utf-8"))
        resp_str = resp_obj.get("choices")[0].get("message").get("content")

        if len(resp_str) == 0:
            raise InvokeServerUnavailableError("Empty response")

        assistant_prompt_message = AssistantPromptMessage(content=resp_str, tool_calls=[])

        prompt_tokens = self._num_tokens_from_messages(messages=prompt_messages, tools=tools)
        completion_tokens = self._num_tokens_from_messages(messages=[assistant_prompt_message], tools=tools)

        usage = self._calc_response_usage(
            model=model, credentials=credentials, prompt_tokens=prompt_tokens, completion_tokens=completion_tokens
        )

        response = LLMResult(
            model=model,
            prompt_messages=prompt_messages,
            system_fingerprint=None,
            usage=usage,
            message=assistant_prompt_message,
        )

        return response

    def _handle_chat_stream_response(
        self,
        model: str,
        credentials: dict,
 
Download .txt
gitextract_8xwzjunu/

├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── README_JA.md
├── README_ZH.md
├── builtin_tools/
│   └── aws/
│       ├── aws.py
│       ├── aws.yaml
│       └── tools/
│           ├── apply_guardrail.py
│           ├── apply_guardrail.yaml
│           ├── bedrock_retrieve.py
│           ├── bedrock_retrieve.yaml
│           ├── bedrock_retrieve_and_generate.py
│           ├── bedrock_retrieve_and_generate.yaml
│           ├── extract_frame.py
│           ├── extract_frame.yaml
│           ├── lambda_translate_utils.py
│           ├── lambda_translate_utils.yaml
│           ├── lambda_yaml_to_json.py
│           ├── lambda_yaml_to_json.yaml
│           ├── nova_canvas.py
│           ├── nova_canvas.yaml
│           ├── nova_reel.py
│           ├── nova_reel.yaml
│           ├── opensearch_knn_search.py
│           ├── opensearch_knn_search.yaml
│           ├── s3_operator.py
│           ├── s3_operator.yaml
│           ├── sagemaker_audio_to_text.py
│           ├── sagemaker_audio_to_text.yaml
│           ├── sagemaker_chinese_toxicity_detector.py
│           ├── sagemaker_chinese_toxicity_detector.yaml
│           ├── sagemaker_text_rerank.py
│           ├── sagemaker_text_rerank.yaml
│           ├── sagemaker_tts.py
│           ├── sagemaker_tts.yaml
│           ├── transcribe_asr.py
│           └── transcribe_asr.yaml
├── dify.yaml
├── model_provider/
│   └── sagemaker/
│       ├── __init__.py
│       ├── llm/
│       │   ├── __init__.py
│       │   └── llm.py
│       ├── rerank/
│       │   ├── __init__.py
│       │   └── rerank.py
│       ├── sagemaker.py
│       ├── sagemaker.yaml
│       ├── speech2text/
│       │   ├── __init__.py
│       │   └── speech2text.py
│       ├── text_embedding/
│       │   ├── __init__.py
│       │   └── text_embedding.py
│       └── tts/
│           ├── __init__.py
│           └── tts.py
├── notebook/
│   ├── bge-embedding-m3-deploy.ipynb
│   ├── bge-reranker-v2-m3-deploy.ipynb
│   ├── byoc_qwen_rerank_deploy/
│   │   ├── README.md
│   │   ├── app/
│   │   │   ├── inference.py
│   │   │   └── serve
│   │   ├── build_and_push.sh
│   │   ├── deploy_and_test.ipynb
│   │   └── dockerfile
│   ├── cosyvoice/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build_docker.sh
│   │   ├── code/
│   │   │   ├── api_server.py
│   │   │   ├── inference.py
│   │   │   └── serve
│   │   └── cosyvoice_deploy.ipynb
│   ├── cosyvoice_china_region/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── build_docker.sh
│   │   ├── code/
│   │   │   ├── api_server.py
│   │   │   ├── inference.py
│   │   │   └── serve
│   │   └── cosyvoice_deploy.ipynb
│   ├── deploy_lambda_yaml_to_json.md
│   ├── funasr-deploy-china-region.ipynb
│   ├── funasr-deploy.ipynb
│   ├── how_to_deploy.md
│   ├── llm_sagemaker_deploy/
│   │   ├── README.md
│   │   ├── app/
│   │   │   └── serve
│   │   ├── build_and_push.sh
│   │   ├── deploy_and_test.ipynb
│   │   ├── deploy_and_test_qwenvl.ipynb
│   │   └── dockerfile
│   ├── llm_sagemaker_deploy_sglang/
│   │   ├── README.md
│   │   ├── app/
│   │   │   └── serve
│   │   ├── build_and_push.sh
│   │   ├── deploy_and_test.ipynb
│   │   └── dockerfile
│   ├── search_img_by_img/
│   │   └── image_search.ipynb
│   └── whisper-deploy-china-region.ipynb
├── plugins/
│   ├── README.md
│   ├── aws_tools/
│   │   ├── .difyignore
│   │   ├── .gitignore
│   │   ├── GUIDE.md
│   │   ├── PRIVACY.md
│   │   ├── README.md
│   │   ├── main.py
│   │   ├── manifest.yaml
│   │   ├── provider/
│   │   │   ├── aws_tools.py
│   │   │   ├── aws_tools.yaml
│   │   │   └── utils.py
│   │   ├── requirements.txt
│   │   └── tools/
│   │       ├── agentcore-browser-session-manager.py
│   │       ├── agentcore-browser-session-manager.yaml
│   │       ├── agentcore-browser-tool.py
│   │       ├── agentcore-browser-tool.yaml
│   │       ├── agentcore_code_interpreter.py
│   │       ├── agentcore_code_interpreter.yaml
│   │       ├── agentcore_memory.py
│   │       ├── agentcore_memory.yaml
│   │       ├── agentcore_memory_search.py
│   │       ├── agentcore_memory_search.yaml
│   │       ├── apply_guardrail.py
│   │       ├── apply_guardrail.yaml
│   │       ├── bedrock_retrieve.py
│   │       ├── bedrock_retrieve.yaml
│   │       ├── bedrock_retrieve_and_generate.py
│   │       ├── bedrock_retrieve_and_generate.yaml
│   │       ├── dynamodb_manager.py
│   │       ├── dynamodb_manager.yaml
│   │       ├── extract_frame.py
│   │       ├── extract_frame.yaml
│   │       ├── lambda_translate_utils.py
│   │       ├── lambda_translate_utils.yaml
│   │       ├── lambda_yaml_to_json.py
│   │       ├── lambda_yaml_to_json.yaml
│   │       ├── nova_canvas.py
│   │       ├── nova_canvas.yaml
│   │       ├── nova_reel.py
│   │       ├── nova_reel.yaml
│   │       ├── opensearch_knn_search.py
│   │       ├── opensearch_knn_search.yaml
│   │       ├── s3_operator.py
│   │       ├── s3_operator.yaml
│   │       ├── sagemaker_chinese_toxicity_detector.py
│   │       ├── sagemaker_chinese_toxicity_detector.yaml
│   │       ├── sagemaker_text_rerank.py
│   │       ├── sagemaker_text_rerank.yaml
│   │       ├── sagemaker_tts.py
│   │       ├── sagemaker_tts.yaml
│   │       ├── transcribe_asr.py
│   │       ├── transcribe_asr.yaml
│   │       ├── translation_evaluator.py
│   │       └── translation_evaluator.yaml
│   ├── aws_tools.difypkg
│   ├── bedrock/
│   │   ├── .difyignore
│   │   ├── GUIDE.md
│   │   ├── PRIVACY.md
│   │   ├── README.md
│   │   ├── main.py
│   │   ├── manifest.yaml
│   │   ├── models/
│   │   │   ├── llm/
│   │   │   │   ├── _position.yaml
│   │   │   │   ├── ai21.yaml
│   │   │   │   ├── amazon-nova.yaml
│   │   │   │   ├── anthropic-claude.yaml
│   │   │   │   ├── cache_config.py
│   │   │   │   ├── cohere.yaml
│   │   │   │   ├── deepseek.yaml
│   │   │   │   ├── llm.py
│   │   │   │   ├── meta-llama.yaml
│   │   │   │   ├── mistral.yaml
│   │   │   │   ├── model_configurations/
│   │   │   │   │   ├── claude-3-5-haiku.yaml
│   │   │   │   │   ├── claude-3-5-sonnet.yaml
│   │   │   │   │   ├── claude-3-7-sonnet.yaml
│   │   │   │   │   ├── claude-3-haiku.yaml
│   │   │   │   │   ├── claude-3-opus.yaml
│   │   │   │   │   ├── claude-3-sonnet.yaml
│   │   │   │   │   ├── claude-4-opus.yaml
│   │   │   │   │   ├── claude-4-sonnet.yaml
│   │   │   │   │   ├── cohere-command-light.yaml
│   │   │   │   │   ├── cohere-command-r.yaml
│   │   │   │   │   ├── cohere-command-rplus.yaml
│   │   │   │   │   ├── cohere-command.yaml
│   │   │   │   │   ├── nova-lite.yaml
│   │   │   │   │   ├── nova-micro.yaml
│   │   │   │   │   └── nova-pro.yaml
│   │   │   │   ├── model_ids.py
│   │   │   │   ├── openai.yaml
│   │   │   │   └── qwen.yaml
│   │   │   ├── rerank/
│   │   │   │   ├── amazon.rerank-v1.yaml
│   │   │   │   ├── cohere.rerank-v3-5.yaml
│   │   │   │   ├── model_ids.py
│   │   │   │   └── rerank.py
│   │   │   └── text_embedding/
│   │   │       ├── amazon.nova-2-multimodal-embeddings-v1.yaml
│   │   │       ├── amazon.titan-embed-text-v1.yaml
│   │   │       ├── amazon.titan-embed-text-v2.yaml
│   │   │       ├── cohere.embed-english-v3.yaml
│   │   │       ├── cohere.embed-multilingual-v3.yaml
│   │   │       ├── model_ids.py
│   │   │       └── text_embedding.py
│   │   ├── provider/
│   │   │   ├── bedrock.py
│   │   │   ├── bedrock.yaml
│   │   │   └── get_bedrock_client.py
│   │   ├── requirements.txt
│   │   └── utils/
│   │       ├── __init__.py
│   │       └── inference_profile.py
│   ├── bedrock.difypkg
│   ├── sagemaker/
│   │   ├── .difyignore
│   │   ├── .gitignore
│   │   ├── GUIDE.md
│   │   ├── PRIVACY.md
│   │   ├── README.md
│   │   ├── main.py
│   │   ├── manifest.yaml
│   │   ├── models/
│   │   │   ├── llm/
│   │   │   │   ├── __init__.py
│   │   │   │   └── llm.py
│   │   │   ├── rerank/
│   │   │   │   ├── __init__.py
│   │   │   │   └── rerank.py
│   │   │   ├── speech2text/
│   │   │   │   ├── __init__.py
│   │   │   │   └── speech2text.py
│   │   │   ├── text_embedding/
│   │   │   │   ├── __init__.py
│   │   │   │   └── text_embedding.py
│   │   │   └── tts/
│   │   │       ├── __init__.py
│   │   │       └── tts.py
│   │   ├── provider/
│   │   │   ├── sagemaker.py
│   │   │   └── sagemaker.yaml
│   │   └── requirements.txt
│   └── sagemaker.difypkg
└── workflow/
    ├── ASR_Transcribe.yml
    ├── AgentCore-Memory-1.yml
    ├── AgentCore-Memory-2.yml
    ├── LLM-Finetuning-Dataflow-dify.yml
    ├── README.md
    ├── Sagemaker-Bge-Rerank.yml
    ├── andrew_translation_agent.yml
    ├── apply_guardrails.yml
    ├── basic_rag_sample.yml
    ├── bedrock_knowledge_retreival+Chatbot .yml
    ├── chat-with-browser.yml
    ├── claude3_code_translation.yml
    ├── claude_code_translation.yml
    ├── code_interpreter_demo.yml
    ├── edu_question_gen.yml
    ├── eks_upgrade_planning/
    │   ├── README.md
    │   ├── README_zh.md
    │   ├── eks_cluster_info.py
    │   ├── eks_upgrade_planning.yml
    │   └── requirements.txt
    ├── generate_image_video.yml
    ├── marketing-copywriting.yml
    ├── mcp_server_integration.yml
    ├── opensearch_img_search.yml
    ├── rag_based_bot_with_tts.yml
    ├── rag_based_chatbot_for_nextcloud.yml
    ├── s3_rag.yml
    ├── sagemaker_rerank_workflow.yml
    ├── simple_kimi.yml
    ├── svg_designer.yml
    └── term_based_translation_workflow.yml
Download .txt
SYMBOL INDEX (431 symbols across 67 files)

FILE: builtin_tools/aws/aws.py
  class SageMakerProvider (line 6) | class SageMakerProvider(BuiltinToolProviderController):
    method _validate_credentials (line 7) | def _validate_credentials(self, credentials: dict) -> None:

FILE: builtin_tools/aws/tools/apply_guardrail.py
  class GuardrailParameters (line 16) | class GuardrailParameters(BaseModel):
  class ApplyGuardrailTool (line 24) | class ApplyGuardrailTool(BuiltinTool):
    method _invoke (line 25) | def _invoke(

FILE: builtin_tools/aws/tools/bedrock_retrieve.py
  class BedrockRetrieveTool (line 11) | class BedrockRetrieveTool(BuiltinTool):
    method _bedrock_retrieve (line 16) | def _bedrock_retrieve(
    method _invoke (line 73) | def _invoke(
    method validate_parameters (line 151) | def validate_parameters(self, parameters: dict[str, Any]) -> None:

FILE: builtin_tools/aws/tools/bedrock_retrieve_and_generate.py
  class BedrockRetrieveAndGenerateTool (line 10) | class BedrockRetrieveAndGenerateTool(BuiltinTool):
    method _invoke (line 13) | def _invoke(
    method validate_parameters (line 111) | def validate_parameters(self, parameters: dict[str, Any]) -> None:

FILE: builtin_tools/aws/tools/extract_frame.py
  class FrameExtractor (line 15) | class FrameExtractor(BuiltinTool):
    method _extract_specific_frames (line 16) | def _extract_specific_frames(self, gif_path, output_folder, frame_coun...
    method _clean_temp_dir (line 68) | def _clean_temp_dir(self, temp_dir):
    method _invoke (line 82) | def _invoke(

FILE: builtin_tools/aws/tools/lambda_translate_utils.py
  class LambdaTranslateUtilsTool (line 10) | class LambdaTranslateUtilsTool(BuiltinTool):
    method _invoke_lambda (line 13) | def _invoke_lambda(self, text_content, src_lang, dest_lang, model_id, ...
    method _invoke (line 32) | def _invoke(

FILE: builtin_tools/aws/tools/lambda_yaml_to_json.py
  class LambdaYamlToJsonTool (line 17) | class LambdaYamlToJsonTool(BuiltinTool):
    method _invoke_lambda (line 20) | def _invoke_lambda(self, lambda_name: str, yaml_content: str) -> str:
    method _invoke (line 38) | def _invoke(

FILE: builtin_tools/aws/tools/nova_canvas.py
  class NovaCanvasTool (line 19) | class NovaCanvasTool(BuiltinTool):
    method _invoke (line 20) | def _invoke(
    method _validate_color_string (line 192) | def _validate_color_string(self, color_string) -> bool:
    method get_runtime_parameters (line 199) | def get_runtime_parameters(self) -> list[ToolParameter]:

FILE: builtin_tools/aws/tools/nova_reel.py
  class NovaReelTool (line 32) | class NovaReelTool(BuiltinTool):
    method _invoke (line 33) | def _invoke(
    method _validate_and_extract_parameters (line 76) | def _validate_and_extract_parameters(
    method _initialize_aws_clients (line 108) | def _initialize_aws_clients(self, region: str) -> tuple[Any, Any]:
    method _prepare_model_input (line 114) | def _prepare_model_input(self, params: dict[str, Any], s3_client: Any)...
    method _process_and_validate_image (line 154) | def _process_and_validate_image(self, image_data: bytes) -> Union[Imag...
    method _get_image_from_s3 (line 205) | def _get_image_from_s3(self, s3_client: Any, s3_uri: str) -> Optional[...
    method _start_video_generation (line 214) | def _start_video_generation(self, bedrock: Any, model_input: dict[str,...
    method _handle_generation_mode (line 222) | def _handle_generation_mode(
    method _wait_for_completion (line 237) | def _wait_for_completion(self, bedrock: Any, s3_client: Any, invocatio...
    method _handle_completed_video (line 254) | def _handle_completed_video(self, s3_client: Any, video_path: str) -> ...
    method get_runtime_parameters (line 274) | def get_runtime_parameters(self) -> list[ToolParameter]:

FILE: builtin_tools/aws/tools/opensearch_knn_search.py
  class OpenSearchRetrieveTool (line 13) | class OpenSearchRetrieveTool(BuiltinTool):
    method _get_embedding (line 18) | def _get_embedding(self, model_id:str, text:str=None, image_path:str=N...
    method _search_by_aos_knn (line 67) | def _search_by_aos_knn(self, q_embedding, index_name:str, embedding_fi...
    method _invoke (line 94) | def _invoke(

FILE: builtin_tools/aws/tools/s3_operator.py
  class S3Operator (line 10) | class S3Operator(BuiltinTool):
    method _invoke (line 13) | def _invoke(

FILE: builtin_tools/aws/tools/sagemaker_audio_to_text.py
  class WhisperTranscriptionTool (line 12) | class WhisperTranscriptionTool(BuiltinTool):
    method _get_s3_object_from_url (line 17) | def _get_s3_object_from_url(self, s3_url: str) -> tuple[str, str]:
    method _download_from_s3 (line 24) | def _download_from_s3(self, s3_url: str) -> str:
    method _invoke_sagemaker (line 41) | def _invoke_sagemaker(self, audio_data: bytes, endpoint: str):
    method _invoke (line 53) | def _invoke(self,

FILE: builtin_tools/aws/tools/sagemaker_chinese_toxicity_detector.py
  class ContentModerationTool (line 13) | class ContentModerationTool(BuiltinTool):
    method _invoke_sagemaker (line 17) | def _invoke_sagemaker(self, payload: dict, endpoint: str):
    method _invoke (line 39) | def _invoke(

FILE: builtin_tools/aws/tools/sagemaker_text_rerank.py
  class SageMakerReRankTool (line 11) | class SageMakerReRankTool(BuiltinTool):
    method _sagemaker_rerank (line 15) | def _sagemaker_rerank(self, query_input: str, docs: list[str], rerank_...
    method _invoke (line 27) | def _invoke(

FILE: builtin_tools/aws/tools/sagemaker_tts.py
  class TTSModelType (line 11) | class TTSModelType(Enum):
  class SageMakerTTSTool (line 18) | class SageMakerTTSTool(BuiltinTool):
    method _detect_lang_code (line 24) | def _detect_lang_code(self, content: str, map_dict: Optional[dict] = N...
    method _build_tts_payload (line 31) | def _build_tts_payload(
    method _invoke_sagemaker (line 52) | def _invoke_sagemaker(self, payload: dict, endpoint: str):
    method _invoke (line 62) | def _invoke(

FILE: builtin_tools/aws/tools/transcribe_asr.py
  function is_url (line 131) | def is_url(text):
  function upload_file_from_url_to_s3 (line 150) | def upload_file_from_url_to_s3(s3_client, url, bucket_name, s3_key=None,...
  class TranscribeTool (line 210) | class TranscribeTool(BuiltinTool):
    method _transcribe_audio (line 220) | def _transcribe_audio(self, audio_file_uri, file_type, **extra_args):
    method _download_and_read_transcript (line 244) | def _download_and_read_transcript(self, transcript_file_uri: str, max_...
    method _invoke (line 330) | def _invoke(

FILE: model_provider/sagemaker/llm/llm.py
  function inference (line 45) | def inference(predictor, messages: list[dict[str, Any]], params: dict[st...
  class SageMakerLargeLanguageModel (line 79) | class SageMakerLargeLanguageModel(LargeLanguageModel):
    method _handle_chat_generate_response (line 88) | def _handle_chat_generate_response(
    method _handle_chat_stream_response (line 124) | def _handle_chat_stream_response(
    method _invoke (line 217) | def _invoke(
    method _convert_prompt_message_to_dict (line 286) | def _convert_prompt_message_to_dict(self, message: PromptMessage) -> d...
    method _num_tokens_from_messages (line 328) | def _num_tokens_from_messages(
    method get_num_tokens (line 386) | def get_num_tokens(
    method validate_credentials (line 408) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_error_mapping (line 423) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method get_customizable_model_schema (line 440) | def get_customizable_model_schema(self, model: str, credentials: dict)...

FILE: model_provider/sagemaker/rerank/rerank.py
  class SageMakerRerankModel (line 25) | class SageMakerRerankModel(RerankModel):
    method _sagemaker_rerank (line 32) | def _sagemaker_rerank(self, query_input: str, docs: list[str], rerank_...
    method _invoke (line 44) | def _invoke(
    method validate_credentials (line 118) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_error_mapping (line 143) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method get_customizable_model_schema (line 160) | def get_customizable_model_schema(self, model: str, credentials: dict)...

FILE: model_provider/sagemaker/sagemaker.py
  class SageMakerProvider (line 10) | class SageMakerProvider(ModelProvider):
    method validate_provider_credentials (line 11) | def validate_provider_credentials(self, credentials: dict) -> None:
  function buffer_to_s3 (line 22) | def buffer_to_s3(s3_client: Any, file: IO[bytes], bucket: str, s3_prefix...
  function generate_presigned_url (line 31) | def generate_presigned_url(s3_client: Any, file: IO[bytes], bucket_name:...

FILE: model_provider/sagemaker/speech2text/speech2text.py
  class SageMakerSpeech2TextModel (line 24) | class SageMakerSpeech2TextModel(Speech2TextModel):
    method _invoke (line 32) | def _invoke(self, model: str, credentials: dict, file: IO[bytes], user...
    method validate_credentials (line 95) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_error_mapping (line 106) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method get_customizable_model_schema (line 123) | def get_customizable_model_schema(self, model: str, credentials: dict)...

FILE: model_provider/sagemaker/text_embedding/text_embedding.py
  function batch_generator (line 30) | def batch_generator(generator, batch_size):
  class SageMakerEmbeddingModel (line 38) | class SageMakerEmbeddingModel(TextEmbeddingModel):
    method _sagemaker_embedding (line 45) | def _sagemaker_embedding(self, sm_client, endpoint_name, content_list:...
    method _invoke (line 56) | def _invoke(
    method get_num_tokens (line 122) | def get_num_tokens(self, model: str, credentials: dict, texts: list[st...
    method validate_credentials (line 133) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _calc_response_usage (line 146) | def _calc_response_usage(self, model: str, credentials: dict, tokens: ...
    method _invoke_error_mapping (line 174) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method get_customizable_model_schema (line 183) | def get_customizable_model_schema(self, model: str, credentials: dict)...

FILE: model_provider/sagemaker/tts/tts.py
  class TTSModelType (line 26) | class TTSModelType(Enum):
  class SageMakerText2SpeechModel (line 33) | class SageMakerText2SpeechModel(TTSModel):
    method __init__ (line 38) | def __init__(self):
    method validate_credentials (line 70) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _detect_lang_code (line 80) | def _detect_lang_code(self, content: str, map_dict: Optional[dict] = N...
    method _build_tts_payload (line 88) | def _build_tts_payload(
    method _invoke (line 109) | def _invoke(
    method get_customizable_model_schema (line 162) | def get_customizable_model_schema(self, model: str, credentials: dict)...
    method _invoke_error_mapping (line 178) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method _get_model_default_voice (line 195) | def _get_model_default_voice(self, model: str, credentials: dict) -> Any:
    method _get_model_word_limit (line 198) | def _get_model_word_limit(self, model: str, credentials: dict) -> int:
    method _get_model_audio_type (line 201) | def _get_model_audio_type(self, model: str, credentials: dict) -> str:
    method _get_model_workers_limit (line 204) | def _get_model_workers_limit(self, model: str, credentials: dict) -> int:
    method get_tts_model_voices (line 207) | def get_tts_model_voices(self, model: str, credentials: dict, language...
    method _invoke_sagemaker (line 218) | def _invoke_sagemaker(self, payload: dict, endpoint: str):
    method _tts_invoke_streaming (line 228) | def _tts_invoke_streaming(self, model_type: str, payload: dict, sagema...

FILE: notebook/byoc_qwen_rerank_deploy/app/inference.py
  function main (line 11) | def main() -> int:

FILE: notebook/cosyvoice/code/api_server.py
  class LaunchFailed (line 26) | class LaunchFailed(Exception):
  function lifespan (line 30) | async def lifespan(app: FastAPI):
  function inference_fn (line 42) | def inference_fn(data):
  function ping (line 59) | async def ping():
  function invocations (line 63) | async def invocations(request: Request):
  function roles (line 69) | async def roles():

FILE: notebook/cosyvoice/code/inference.py
  class SftRequest (line 43) | class SftRequest(BaseModel):
  class ZeroShotRequest (line 47) | class ZeroShotRequest(BaseModel):
  class InstructRequest (line 52) | class InstructRequest(BaseModel):
  function validate_sft_request (line 57) | def validate_sft_request(data: dict) -> SftRequest:
  function validate_zero_shot_request (line 60) | def validate_zero_shot_request(data: dict) -> ZeroShotRequest:
  function validate_instruct_request (line 63) | def validate_instruct_request(data: dict) -> InstructRequest:
  function save_to_s3 (line 66) | def save_to_s3(output) -> str:
  function generate_presigned_url (line 83) | def generate_presigned_url(s3_uri, expiration=3600):
  function get_audio (line 107) | def get_audio(url):
  class CosyVoiceService (line 112) | class CosyVoiceService():
    method __init__ (line 113) | def __init__(self, model_dir:str):
    method list_avaliable_spks (line 117) | def list_avaliable_spks(self):
    method predict_fn (line 120) | def predict_fn(self, request):

FILE: notebook/cosyvoice_china_region/code/api_server.py
  class LaunchFailed (line 26) | class LaunchFailed(Exception):
  function lifespan (line 30) | async def lifespan(app: FastAPI):
  function inference_fn (line 42) | def inference_fn(data):
  function ping (line 59) | async def ping():
  function invocations (line 63) | async def invocations(request: Request):
  function roles (line 69) | async def roles():

FILE: notebook/cosyvoice_china_region/code/inference.py
  class SftRequest (line 43) | class SftRequest(BaseModel):
  class ZeroShotRequest (line 47) | class ZeroShotRequest(BaseModel):
  class InstructRequest (line 52) | class InstructRequest(BaseModel):
  function validate_sft_request (line 57) | def validate_sft_request(data: dict) -> SftRequest:
  function validate_zero_shot_request (line 60) | def validate_zero_shot_request(data: dict) -> ZeroShotRequest:
  function validate_instruct_request (line 63) | def validate_instruct_request(data: dict) -> InstructRequest:
  function save_to_s3 (line 66) | def save_to_s3(output) -> str:
  function generate_presigned_url (line 83) | def generate_presigned_url(s3_uri, expiration=3600):
  function get_audio (line 107) | def get_audio(url):
  class CosyVoiceService (line 112) | class CosyVoiceService():
    method __init__ (line 113) | def __init__(self, model_dir:str):
    method list_avaliable_spks (line 117) | def list_avaliable_spks(self):
    method predict_fn (line 120) | def predict_fn(self, request):

FILE: plugins/aws_tools/provider/aws_tools.py
  class AwsToolsProvider (line 7) | class AwsToolsProvider(ToolProvider):
    method _validate_credentials (line 8) | def _validate_credentials(self, credentials: dict[str, Any]) -> None:

FILE: plugins/aws_tools/provider/utils.py
  class ParameterStoreManager (line 7) | class ParameterStoreManager:
    method __init__ (line 10) | def __init__(self, region_name: str = 'us-east-1'):
    method get_parameter (line 13) | def get_parameter(self, name: str, decrypt: bool = True, as_dict: bool...
    method put_parameter (line 43) | def put_parameter(self, name: str, value: Union[str, Dict, Any], param...
    method delete_parameter (line 74) | def delete_parameter(self, name: str) -> bool:

FILE: plugins/aws_tools/tools/agentcore-browser-session-manager.py
  class AgentcoreBrowserSessionManagerTool (line 28) | class AgentcoreBrowserSessionManagerTool(Tool):
    method _init_browser_session (line 30) | def _init_browser_session(self, aws_region, session_timeout_seconds) -...
    method _close_browser_session (line 61) | def _close_browser_session(self, aws_region, session_id) -> dict:
    method _invoke (line 76) | def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolIn...

FILE: plugins/aws_tools/tools/agentcore-browser-tool.py
  class AgentcoreBrowserToolTool (line 34) | class AgentcoreBrowserToolTool(Tool):
    method __init__ (line 38) | def __init__(self, **kwargs):
    method _setup_temp_dir (line 42) | def _setup_temp_dir(self):
    method _get_session (line 59) | def _get_session(self, session_id: str) -> dict:
    method _set_session (line 63) | def _set_session(self, session_id: str, browser, page, playwright):
    method _init_browser_session (line 71) | async def _init_browser_session(self, browser_session_id:str, aws_regi...
    method _cleanup_browser (line 137) | async def _cleanup_browser(self, session_id: str = None):
    method _browse_url (line 153) | async def _browse_url(self, browser_session_id:str, url: str, wait_tim...
    method _search_web (line 196) | async def _search_web(self, browser_session_id:str, query: str, wait_t...
    method _extract_content (line 260) | async def _extract_content(self, browser_session_id:str, url: str = No...
    method _fill_form (line 350) | async def _fill_form(self, browser_session_id:str, url: str = None, fo...
    method _execute_script (line 425) | async def _execute_script(self, browser_session_id:str, url: str = Non...
    method _invoke (line 459) | def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolIn...

FILE: plugins/aws_tools/tools/agentcore_code_interpreter.py
  class AgentcoreCodeInterpreterTool (line 9) | class AgentcoreCodeInterpreterTool(Tool):
    method _invoke (line 10) | def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolIn...
    method execute (line 15) | def execute(self, language=None, code=None, command=None, session_id=N...
    method create_client (line 60) | def create_client(self, aws_ak=None, aws_sk=None, aws_region=None, ser...
    method create_code_interpreter (line 70) | def create_code_interpreter(self, client):
    method exec_code_internal (line 80) | def exec_code_internal(self, client, code_interpreter_id, session_id, ...
    method exec_command_internal (line 94) | def exec_command_internal(self, client, code_interpreter_id, session_i...
    method init_session (line 108) | def init_session(self, data_client, ci_id):
    method get_tool_result (line 117) | def get_tool_result(self, response):

FILE: plugins/aws_tools/tools/agentcore_memory.py
  class AgentCoreMemoryTool (line 25) | class AgentCoreMemoryTool(Tool):
    method _clean_id_parameter (line 31) | def _clean_id_parameter(self, value: str) -> str:
    method _initialize_memory_client (line 40) | def _initialize_memory_client(self, tool_parameters: dict[str, Any]) -...
    method _create_new_memory_resource (line 72) | def _create_new_memory_resource(self, tool_parameters: dict[str, Any])...
    method _record_information (line 129) | def _record_information(self, tool_parameters: dict[str, Any]) -> Gene...
    method _retrieve_history (line 180) | def _retrieve_history(self, tool_parameters: dict[str, Any]) -> Genera...
    method _invoke (line 259) | def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolIn...

FILE: plugins/aws_tools/tools/agentcore_memory_search.py
  class AgentCoreMemorySearchTool (line 25) | class AgentCoreMemorySearchTool(Tool):
    method _clean_id_parameter (line 28) | def _clean_id_parameter(self, value: str) -> str:
    method _initialize_memory_client (line 37) | def _initialize_memory_client(self, tool_parameters: dict[str, Any]) -...
    method _search_memories (line 69) | def _search_memories(self, tool_parameters: dict[str, Any]) -> Generat...
    method _invoke (line 154) | def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolIn...

FILE: plugins/aws_tools/tools/apply_guardrail.py
  class GuardrailParameters (line 16) | class GuardrailParameters(BaseModel):
  class ApplyGuardrailTool (line 24) | class ApplyGuardrailTool(Tool):
    method _invoke (line 25) | def _invoke(

FILE: plugins/aws_tools/tools/bedrock_retrieve.py
  class BedrockRetrieveTool (line 11) | class BedrockRetrieveTool(Tool):
    method convert_to_dify_kb_format (line 16) | def convert_to_dify_kb_format(self, kb_repsonse):
    method _bedrock_retrieve (line 63) | def _bedrock_retrieve(
    method _invoke (line 111) | def _invoke(
    method validate_parameters (line 189) | def validate_parameters(self, parameters: dict[str, Any]) -> None:

FILE: plugins/aws_tools/tools/bedrock_retrieve_and_generate.py
  class BedrockRetrieveAndGenerateTool (line 10) | class BedrockRetrieveAndGenerateTool(Tool):
    method _format_text_with_citations (line 13) | def _format_text_with_citations(self, result: dict[str, Any]) -> str:
    method _invoke (line 33) | def _invoke(
    method validate_parameters (line 131) | def validate_parameters(self, parameters: dict[str, Any]) -> None:

FILE: plugins/aws_tools/tools/dynamodb_manager.py
  class DynamoDBManager (line 11) | class DynamoDBManager(Tool):
    method _invoke (line 15) | def _invoke(
    method _create_table (line 52) | def _create_table(self, params: dict) -> str:
    method _put_item (line 80) | def _put_item(self, params: dict) -> str:
    method _get_item (line 104) | def _get_item(self, params: dict) -> str:
    method _delete_item (line 126) | def _delete_item(self, params: dict) -> str:
    method _scan (line 145) | def _scan(self, params: dict) -> dict:

FILE: plugins/aws_tools/tools/extract_frame.py
  class FrameExtractor (line 10) | class FrameExtractor(Tool):
    method _extract_specific_frames (line 11) | def _extract_specific_frames(self, gif_path, output_folder, frame_coun...
    method _clean_temp_dir (line 63) | def _clean_temp_dir(self, temp_dir):
    method _invoke (line 77) | def _invoke(

FILE: plugins/aws_tools/tools/lambda_translate_utils.py
  class LambdaTranslateUtilsTool (line 10) | class LambdaTranslateUtilsTool(Tool):
    method _invoke_lambda (line 13) | def _invoke_lambda(self, text_content, src_lang, dest_lang, model_id, ...
    method _invoke (line 32) | def _invoke(

FILE: plugins/aws_tools/tools/lambda_yaml_to_json.py
  class LambdaYamlToJsonTool (line 18) | class LambdaYamlToJsonTool(Tool):
    method _invoke_lambda (line 21) | def _invoke_lambda(self, lambda_name: str, yaml_content: str) -> str:
    method _invoke (line 39) | def _invoke(

FILE: plugins/aws_tools/tools/nova_canvas.py
  class NovaCanvasTool (line 24) | class NovaCanvasTool(Tool):
    method _invoke (line 25) | def _invoke(
    method _validate_color_string (line 194) | def _validate_color_string(self, color_string) -> bool:
    method get_runtime_parameters (line 201) | def get_runtime_parameters(self) -> list[ToolParameter]:

FILE: plugins/aws_tools/tools/nova_reel.py
  class NovaReelTool (line 41) | class NovaReelTool(Tool):
    method _invoke (line 42) | def _invoke(
    method _validate_and_extract_parameters (line 85) | def _validate_and_extract_parameters(
    method _initialize_aws_clients (line 117) | def _initialize_aws_clients(self, region: str) -> tuple[Any, Any]:
    method _prepare_model_input (line 123) | def _prepare_model_input(self, params: dict[str, Any], s3_client: Any)...
    method _process_and_validate_image (line 163) | def _process_and_validate_image(self, image_data: bytes) -> Union[Imag...
    method _get_image_from_s3 (line 214) | def _get_image_from_s3(self, s3_client: Any, s3_uri: str) -> Optional[...
    method _start_video_generation (line 223) | def _start_video_generation(self, bedrock: Any, model_input: dict[str,...
    method _handle_generation_mode (line 231) | def _handle_generation_mode(
    method _wait_for_completion (line 246) | def _wait_for_completion(self, bedrock: Any, s3_client: Any, invocatio...
    method _handle_completed_video (line 263) | def _handle_completed_video(self, s3_client: Any, video_path: str) -> ...
    method get_runtime_parameters (line 283) | def get_runtime_parameters(self) -> list[ToolParameter]:

FILE: plugins/aws_tools/tools/opensearch_knn_search.py
  class OpenSearchRetrieveTool (line 13) | class OpenSearchRetrieveTool(Tool):
    method _get_embedding (line 18) | def _get_embedding(self, model_id:str, text:str=None, image_path:str=N...
    method _search_by_aos_knn (line 67) | def _search_by_aos_knn(self, q_embedding, index_name:str, embedding_fi...
    method _invoke (line 94) | def _invoke(

FILE: plugins/aws_tools/tools/s3_operator.py
  class S3Operator (line 15) | class S3Operator(Tool):
    method _invoke (line 18) | def _invoke(

FILE: plugins/aws_tools/tools/sagemaker_chinese_toxicity_detector.py
  class ContentModerationTool (line 15) | class ContentModerationTool(Tool):
    method _invoke_sagemaker (line 19) | def _invoke_sagemaker(self, payload: dict, endpoint: str):
    method _invoke (line 41) | def _invoke(

FILE: plugins/aws_tools/tools/sagemaker_text_rerank.py
  class SageMakerReRankTool (line 11) | class SageMakerReRankTool(Tool):
    method _sagemaker_rerank (line 15) | def _sagemaker_rerank(self, query_input: str, docs: list[str], rerank_...
    method _invoke (line 27) | def _invoke(

FILE: plugins/aws_tools/tools/sagemaker_tts.py
  class TTSModelType (line 12) | class TTSModelType(Enum):
  class SageMakerTTSTool (line 19) | class SageMakerTTSTool(Tool):
    method _detect_lang_code (line 25) | def _detect_lang_code(self, content: str, map_dict: Optional[dict] = N...
    method _build_tts_payload (line 32) | def _build_tts_payload(
    method _invoke_sagemaker (line 53) | def _invoke_sagemaker(self, payload: dict, endpoint: str):
    method _invoke (line 63) | def _invoke(

FILE: plugins/aws_tools/tools/transcribe_asr.py
  function is_url (line 132) | def is_url(text):
  function upload_file_from_url_to_s3 (line 151) | def upload_file_from_url_to_s3(s3_client, url, bucket_name, s3_key=None,...
  class TranscribeTool (line 211) | class TranscribeTool(Tool):
    method _transcribe_audio (line 221) | def _transcribe_audio(self, audio_file_uri, file_type, **extra_args):
    method _download_and_read_transcript (line 245) | def _download_and_read_transcript(self, transcript_file_uri: str, max_...
    method _invoke (line 331) | def _invoke(

FILE: plugins/aws_tools/tools/translation_evaluator.py
  function tokenize_zh (line 18) | def tokenize_zh(text):
  function calculate_bleu (line 21) | def calculate_bleu(references, hypotheses , weights=(0.25, 0.25, 0.25, 0...
  function chinese_meteor_score (line 39) | def chinese_meteor_score(references, hypothesis, alpha=0.9, beta=3.0, ga...
  function calculate_nist (line 55) | def calculate_nist(references, hypotheses):
  function evaluate_with_metric (line 65) | def evaluate_with_metric(references, hypotheses):
  function evaluate_with_model (line 80) | def evaluate_with_model(sagemaker_endpoint, source, translation):
  class TranslationEvalTool (line 83) | class TranslationEvalTool(Tool):
    method _invoke (line 87) | def _invoke(

FILE: plugins/bedrock/models/llm/cache_config.py
  function is_cache_supported (line 77) | def is_cache_supported(model_id: str) -> bool:
  function get_cache_config (line 90) | def get_cache_config(model_id: str) -> dict:

FILE: plugins/bedrock/models/llm/llm.py
  class BedrockLargeLanguageModel (line 75) | class BedrockLargeLanguageModel(LargeLanguageModel):
    method _find_model_info (line 106) | def _find_model_info(model_id):
    method _code_block_mode_wrapper (line 113) | def _code_block_mode_wrapper(
    method _invoke (line 146) | def _invoke(
    method _get_model_info (line 238) | def _get_model_info(self, model: str, credentials: dict, model_paramet...
    method _generate_with_converse (line 317) | def _generate_with_converse(
    method _handle_converse_response (line 479) | def _handle_converse_response(
    method _extract_tool_use (line 541) | def _extract_tool_use(self, content: dict) -> tuple[str, dict]:
    method _handle_converse_stream_response (line 553) | def _handle_converse_stream_response(
    method _convert_converse_api_model_parameters (line 713) | def _convert_converse_api_model_parameters(
    method _convert_converse_prompt_messages (line 760) | def _convert_converse_prompt_messages(self, prompt_messages: list[Prom...
    method _convert_converse_tool_config (line 827) | def _convert_converse_tool_config(self, tools: Optional[list[PromptMes...
    method _convert_prompt_message_to_dict (line 844) | def _convert_prompt_message_to_dict(self, message: PromptMessage) -> d...
    method get_num_tokens (line 932) | def get_num_tokens(
    method get_customizable_model_schema (line 968) | def get_customizable_model_schema(self, model: str, credentials: dict)...
    method validate_credentials (line 1082) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _list_foundation_models (line 1112) | def _list_foundation_models(self, credentials: dict) -> list[str]:
    method _convert_one_message_to_text (line 1141) | def _convert_one_message_to_text(
    method _convert_messages_to_prompt (line 1172) | def _convert_messages_to_prompt(
    method _create_payload (line 1194) | def _create_payload(
    method _generate (line 1234) | def _generate(
    method _handle_generate_response (line 1289) | def _handle_generate_response(
    method _handle_generate_stream_response (line 1340) | def _handle_generate_stream_response(
    method _invoke_error_mapping (line 1424) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method _map_client_to_invoke_error (line 1441) | def _map_client_to_invoke_error(self, error_code: str, error_msg: str)...
    method _get_inference_profile_parameter_rules (line 1468) | def _get_inference_profile_parameter_rules(self, model_schema, underly...
    method _model_id_matches_schema (line 1501) | def _model_id_matches_schema(self, model_id: str, model_schema) -> bool:
    method _map_model_id_to_name (line 1530) | def _map_model_id_to_name(self, model_id: str) -> Optional[str]:
    method _get_model_specific_pricing (line 1553) | def _get_model_specific_pricing(self, model: str, model_name: str, mod...
    method _calc_response_usage (line 1638) | def _calc_response_usage(self, model: str, credentials: dict, prompt_t...

FILE: plugins/bedrock/models/llm/model_ids.py
  function is_support_cross_region (line 73) | def is_support_cross_region(model_id):
  function get_model_id (line 85) | def get_model_id(model_type, model_name):
  function get_region_area (line 98) | def get_region_area(region_name, prefer_global=False):

FILE: plugins/bedrock/models/rerank/model_ids.py
  function get_model_id (line 17) | def get_model_id(model_type, model_name):
  function get_all_model_choices (line 30) | def get_all_model_choices():

FILE: plugins/bedrock/models/rerank/rerank.py
  class BedrockRerankModel (line 33) | class BedrockRerankModel(RerankModel):
    method _invoke (line 38) | def _invoke(
    method get_customizable_model_schema (line 152) | def get_customizable_model_schema(self, model: str, credentials: dict)...
    method validate_credentials (line 227) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method validate_credentials (line 252) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_error_mapping (line 277) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...

FILE: plugins/bedrock/models/text_embedding/model_ids.py
  function get_model_id (line 20) | def get_model_id(model_type, model_name):
  function get_all_model_choices (line 33) | def get_all_model_choices():

FILE: plugins/bedrock/models/text_embedding/text_embedding.py
  class BedrockTextEmbeddingModel (line 38) | class BedrockTextEmbeddingModel(TextEmbeddingModel):
    method _invoke (line 39) | def _invoke(
    method get_num_tokens (line 155) | def get_num_tokens(self, model: str, credentials: dict, texts: list[st...
    method validate_credentials (line 180) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_error_mapping (line 190) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method _create_payload (line 207) | def _create_payload(
    method _calc_response_usage (line 223) | def _calc_response_usage(self, model: str, credentials: dict, tokens: ...
    method _map_client_to_invoke_error (line 250) | def _map_client_to_invoke_error(self, error_code: str, error_msg: str)...
    method _invoke_bedrock_embedding (line 277) | def _invoke_bedrock_embedding(
    method get_customizable_model_schema (line 305) | def get_customizable_model_schema(self, model: str, credentials: dict)...
    method validate_credentials (line 380) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_multimodal (line 409) | def _invoke_multimodal(
    method _get_image_format (line 496) | def _get_image_format(self, base64_string: str) -> str:

FILE: plugins/bedrock/provider/bedrock.py
  class AmazonBedrockModelProvider (line 14) | class AmazonBedrockModelProvider(ModelProvider):
    method validate_provider_credentials (line 15) | def validate_provider_credentials(self, credentials: Mapping) -> None:
    method validate_model_credentials (line 33) | def validate_model_credentials(self, model: str, model_type: ModelType...
    method _validate_inference_profile (line 62) | def _validate_inference_profile(self, inference_profile_id: str, crede...

FILE: plugins/bedrock/provider/get_bedrock_client.py
  function get_bedrock_client (line 10) | def get_bedrock_client(service_name: str, credentials: Mapping[str, str]):

FILE: plugins/bedrock/utils/inference_profile.py
  function _get_fetch_lock (line 25) | def _get_fetch_lock(cache_key: str) -> threading.Lock:
  function get_inference_profile_info (line 42) | def get_inference_profile_info(inference_profile_id: str, credentials: d...
  function validate_inference_profile (line 108) | def validate_inference_profile(inference_profile_id: str, credentials: d...
  function extract_model_id_from_arn (line 137) | def extract_model_id_from_arn(model_arn: str) -> str:
  function extract_model_info_from_profile (line 151) | def extract_model_info_from_profile(profile_info: dict) -> Dict[str, Any]:

FILE: plugins/sagemaker/models/llm/llm.py
  function inference (line 54) | def inference(predictor, messages: list[dict[str, Any]], params: dict[st...
  class SageMakerLargeLanguageModel (line 89) | class SageMakerLargeLanguageModel(LargeLanguageModel):
    method _handle_chat_generate_response (line 102) | def _handle_chat_generate_response(
    method _handle_chat_stream_response (line 138) | def _handle_chat_stream_response(
    method _refresh_token (line 231) | def _refresh_token(self):
    method _invoke (line 253) | def _invoke(
    method _convert_prompt_message_to_dict (line 343) | def _convert_prompt_message_to_dict(self, message: PromptMessage) -> d...
    method _num_tokens_from_messages (line 385) | def _num_tokens_from_messages(
    method get_num_tokens (line 443) | def get_num_tokens(
    method validate_credentials (line 465) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_error_mapping (line 480) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method get_customizable_model_schema (line 497) | def get_customizable_model_schema(self, model: str, credentials: dict)...

FILE: plugins/sagemaker/models/rerank/rerank.py
  class SageMakerRerankModel (line 24) | class SageMakerRerankModel(RerankModel):
    method _sagemaker_rerank (line 31) | def _sagemaker_rerank(self, query_input: str, docs: list[str], rerank_...
    method _invoke (line 43) | def _invoke(
    method validate_credentials (line 118) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_error_mapping (line 143) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method get_customizable_model_schema (line 160) | def get_customizable_model_schema(self, model: str, credentials: dict)...

FILE: plugins/sagemaker/models/speech2text/speech2text.py
  class SageMakerSpeech2TextModel (line 24) | class SageMakerSpeech2TextModel(Speech2TextModel):
    method _invoke (line 32) | def _invoke(self, model: str, credentials: dict, file: IO[bytes], user...
    method validate_credentials (line 95) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _invoke_error_mapping (line 106) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method get_customizable_model_schema (line 123) | def get_customizable_model_schema(self, model: str, credentials: dict)...

FILE: plugins/sagemaker/models/text_embedding/text_embedding.py
  function batch_generator (line 35) | def batch_generator(generator, batch_size):
  class SageMakerEmbeddingModel (line 43) | class SageMakerEmbeddingModel(TextEmbeddingModel):
    method _sagemaker_embedding (line 50) | def _sagemaker_embedding(self, sm_client, endpoint_name, content_list:...
    method _invoke (line 61) | def _invoke(
    method get_num_tokens (line 128) | def get_num_tokens(self, model: str, credentials: dict, texts: list[st...
    method validate_credentials (line 139) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _calc_response_usage (line 152) | def _calc_response_usage(self, model: str, credentials: dict, tokens: ...
    method _invoke_error_mapping (line 180) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method get_customizable_model_schema (line 189) | def get_customizable_model_schema(self, model: str, credentials: dict)...

FILE: plugins/sagemaker/models/tts/tts.py
  class TTSModelType (line 24) | class TTSModelType(Enum):
  class SageMakerText2SpeechModel (line 31) | class SageMakerText2SpeechModel(TTSModel):
    method __init__ (line 36) | def __init__(self, model_schemas: list[AIModelEntity]) -> None:
    method validate_credentials (line 57) | def validate_credentials(self, model: str, credentials: dict) -> None:
    method _detect_lang_code (line 67) | def _detect_lang_code(self, content: str, map_dict: Optional[dict] = N...
    method _build_tts_payload (line 75) | def _build_tts_payload(
    method _invoke (line 96) | def _invoke(
    method get_customizable_model_schema (line 149) | def get_customizable_model_schema(self, model: str, credentials: dict)...
    method _invoke_error_mapping (line 165) | def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[E...
    method _get_model_default_voice (line 182) | def _get_model_default_voice(self, model: str, credentials: dict) -> Any:
    method _get_model_word_limit (line 185) | def _get_model_word_limit(self, model: str, credentials: dict) -> int:
    method _get_model_audio_type (line 188) | def _get_model_audio_type(self, model: str, credentials: dict) -> str:
    method _get_model_workers_limit (line 191) | def _get_model_workers_limit(self, model: str, credentials: dict) -> int:
    method get_tts_model_voices (line 194) | def get_tts_model_voices(self, model: str, credentials: dict, language...
    method _invoke_sagemaker (line 205) | def _invoke_sagemaker(self, payload: dict, endpoint: str):
    method _tts_invoke_streaming (line 215) | def _tts_invoke_streaming(self, model_type: str, payload: dict, sagema...

FILE: plugins/sagemaker/provider/sagemaker.py
  class SageMakerProvider (line 12) | class SageMakerProvider(ModelProvider):
    method validate_provider_credentials (line 13) | def validate_provider_credentials(self, credentials: dict) -> None:
  function buffer_to_s3 (line 23) | def buffer_to_s3(s3_client: Any, file: IO[bytes], bucket: str, s3_prefix...
  function generate_presigned_url (line 32) | def generate_presigned_url(s3_client: Any, file: IO[bytes], bucket_name:...

FILE: workflow/eks_upgrade_planning/eks_cluster_info.py
  class TokenGenerator (line 15) | class TokenGenerator(object):
    method __init__ (line 16) | def __init__(self, sts_client):
    method get_token (line 19) | def get_token(self, k8s_aws_id):
    method _get_presigned_url (line 27) | def _get_presigned_url(self, k8s_aws_id):
  class STSClientFactory (line 35) | class STSClientFactory(object):
    method __init__ (line 36) | def __init__(self, session):
    method get_sts_client (line 39) | def get_sts_client(self, region_name=None, role_arn=None):
    method _get_role_credentials (line 50) | def _get_role_credentials(self, region_name, role_arn):
    method _register_k8s_aws_id_handlers (line 56) | def _register_k8s_aws_id_handlers(self, sts_client):
    method _retrieve_k8s_aws_id (line 66) | def _retrieve_k8s_aws_id(self, params, context, **kwargs):
    method _inject_k8s_aws_id_header (line 70) | def _inject_k8s_aws_id_header(self, request, **kwargs):
  function get_cluster_info (line 74) | def get_cluster_info(cluster_name, region, profile=None):
  function get_current_version (line 84) | def get_current_version(cluster_info):
  function get_health_issues (line 87) | def get_health_issues(cluster_info):
  function get_compatibility_issues (line 90) | def get_compatibility_issues(cluster_name, region, profile=None):
  function get_addon_compatibility_issues (line 120) | def get_addon_compatibility_issues(compatibility_issues):
  function get_addon_compatible_versions (line 133) | def get_addon_compatible_versions(compatibility_issues):
  function get_deprecated_api_versions (line 139) | def get_deprecated_api_versions(compatibility_issues):
  function get_nodegroups (line 153) | def get_nodegroups(cluster_name, region, profile=None):
  function get_fargate_profiles (line 174) | def get_fargate_profiles(cluster_name, region, profile=None):
  function get_installed_addons (line 184) | def get_installed_addons(cluster_name, region, profile=None):
  function get_addon_upgrade_info (line 201) | def get_addon_upgrade_info(cluster_name, region, current_version, target...
  function check_version_skew (line 351) | def check_version_skew(current_version, min_nodegroup_version, kube_prox...
  function create_temp_cert_file (line 395) | def create_temp_cert_file(cert_data):
  function validate_target_version (line 405) | def validate_target_version(current_version, target_version):
  function connect_to_cluster (line 440) | def connect_to_cluster(cluster_name, region=None, profile=None):
  function get_node_versions (line 485) | def get_node_versions(api_client):
  function get_opensource_addons (line 562) | def get_opensource_addons(api_client, eks_addons=None):
  function extract_helm_info_from_labels (line 730) | def extract_helm_info_from_labels(labels, addon_info):
  function get_image_version (line 763) | def get_image_version(image_string):
  function get_core_components_version (line 785) | def get_core_components_version(api_client, eks_addons):
  function main (line 859) | def main(cluster_name, region, target_version, profile=None):
Condensed preview — 251 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,361K chars).
[
  {
    "path": ".gitignore",
    "chars": 73,
    "preview": "**/.DS_Store\n**/.ipynb_checkpoints\n**/__pycache__\n/venv/\n.idea\n.DS_Store\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 309,
    "preview": "## Code of Conduct\nThis project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-condu"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3160,
    "preview": "# Contributing Guidelines\n\nThank you for your interest in contributing to our project. Whether it's a bug report, new fe"
  },
  {
    "path": "LICENSE",
    "chars": 947,
    "preview": "MIT No Attribution\n\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\nPermission is hereby granted, fr"
  },
  {
    "path": "README.md",
    "chars": 12093,
    "preview": "![cover-v5-optimized](./dify_on_aws.svg)\n\n<p align=\"center\">\n  <a href=\"https://github.com/aws-samples/dify-aws-tool/blo"
  },
  {
    "path": "README_JA.md",
    "chars": 10454,
    "preview": "![cover-v5-optimized](./dify_on_aws.svg)\n\n<p align=\"center\">\n  <a href=\"https://github.com/aws-samples/dify-aws-tool/blo"
  },
  {
    "path": "README_ZH.md",
    "chars": 9936,
    "preview": "![cover-v5-optimized](./dify_on_aws.svg)\n\n<p align=\"center\">\n  <a href=\"https://github.com/aws-samples/dify-aws-tool/blo"
  },
  {
    "path": "builtin_tools/aws/aws.py",
    "chars": 959,
    "preview": "from core.tools.errors import ToolProviderCredentialValidationError\nfrom core.tools.provider.builtin.aws.tools.sagemaker"
  },
  {
    "path": "builtin_tools/aws/aws.yaml",
    "chars": 255,
    "preview": "identity:\n  author: AWS\n  name: aws\n  label:\n    en_US: AWS\n    zh_Hans: 亚马逊云科技\n    pt_BR: AWS\n  description:\n    en_US:"
  },
  {
    "path": "builtin_tools/aws/tools/apply_guardrail.py",
    "chars": 3929,
    "preview": "import json\nimport logging\nfrom typing import Any, Union\n\nimport boto3  # type: ignore\nfrom botocore.exceptions import B"
  },
  {
    "path": "builtin_tools/aws/tools/apply_guardrail.yaml",
    "chars": 3702,
    "preview": "identity:\n  name: apply_guardrail\n  author: AWS\n  label:\n    en_US: Content Moderation Guardrails\n    zh_Hans: 内容审查护栏\nde"
  },
  {
    "path": "builtin_tools/aws/tools/bedrock_retrieve.py",
    "chars": 6365,
    "preview": "import json\nimport operator\nfrom typing import Any, Optional, Union\n\nimport boto3\n\nfrom core.tools.entities.tool_entitie"
  },
  {
    "path": "builtin_tools/aws/tools/bedrock_retrieve.yaml",
    "chars": 4991,
    "preview": "identity:\n  name: bedrock_retrieve\n  author: AWS\n  label:\n    en_US: Bedrock Retrieve\n    zh_Hans: Bedrock检索\n    pt_BR: "
  },
  {
    "path": "builtin_tools/aws/tools/bedrock_retrieve_and_generate.py",
    "chars": 6184,
    "preview": "import json\nfrom typing import Any\n\nimport boto3\n\nfrom core.tools.entities.tool_entities import ToolInvokeMessage\nfrom c"
  },
  {
    "path": "builtin_tools/aws/tools/bedrock_retrieve_and_generate.yaml",
    "chars": 4282,
    "preview": "identity:\n  name: bedrock_retrieve_and_generate\n  author: AWS\n  label:\n    en_US: Bedrock Retrieve and Generate\n    zh_H"
  },
  {
    "path": "builtin_tools/aws/tools/extract_frame.py",
    "chars": 4565,
    "preview": "import os\nimport json\nimport logging\nimport shutil\nimport requests\nfrom PIL import Image\nfrom typing import Any, Union\n\n"
  },
  {
    "path": "builtin_tools/aws/tools/extract_frame.yaml",
    "chars": 1198,
    "preview": "identity:\n  name: extract_frame\n  author: AWS\n  label:\n    en_US: ExtractFrame\n    zh_Hans: 抽帧工具\n    pt_BR: ExtractFrame"
  },
  {
    "path": "builtin_tools/aws/tools/lambda_translate_utils.py",
    "chars": 3186,
    "preview": "import json\nfrom typing import Any, Union\n\nimport boto3  # type: ignore\n\nfrom core.tools.entities.tool_entities import T"
  },
  {
    "path": "builtin_tools/aws/tools/lambda_translate_utils.yaml",
    "chars": 3982,
    "preview": "identity:\n  name: lambda_translate_utils\n  author: AWS\n  label:\n    en_US: TranslateTool\n    zh_Hans: 翻译工具\n    pt_BR: Tr"
  },
  {
    "path": "builtin_tools/aws/tools/lambda_yaml_to_json.py",
    "chars": 2380,
    "preview": "import json\nimport logging\nfrom typing import Any, Union\n\nimport boto3  # type: ignore\n\nfrom core.tools.entities.tool_en"
  },
  {
    "path": "builtin_tools/aws/tools/lambda_yaml_to_json.yaml",
    "chars": 1369,
    "preview": "identity:\n  name: lambda_yaml_to_json\n  author: AWS\n  label:\n    en_US: LambdaYamlToJson\n    zh_Hans: LambdaYamlToJson\n "
  },
  {
    "path": "builtin_tools/aws/tools/nova_canvas.py",
    "chars": 15993,
    "preview": "import base64\nimport json\nimport logging\nimport re\nfrom datetime import datetime\nfrom typing import Any, Union\nfrom urll"
  },
  {
    "path": "builtin_tools/aws/tools/nova_canvas.yaml",
    "chars": 5330,
    "preview": "identity:\n  name: nova_canvas\n  author: AWS\n  label:\n    en_US: AWS Bedrock Nova Canvas\n    zh_Hans: AWS Bedrock Nova Ca"
  },
  {
    "path": "builtin_tools/aws/tools/nova_reel.py",
    "chars": 16740,
    "preview": "import base64\nimport logging\nimport time\nfrom io import BytesIO\nfrom typing import Any, Optional, Union\nfrom urllib.pars"
  },
  {
    "path": "builtin_tools/aws/tools/nova_reel.yaml",
    "chars": 3249,
    "preview": "identity:\n  name: nova_reel\n  author: AWS\n  label:\n    en_US: AWS Bedrock Nova Reel\n    zh_Hans: AWS Bedrock Nova Reel\n "
  },
  {
    "path": "builtin_tools/aws/tools/opensearch_knn_search.py",
    "chars": 5357,
    "preview": "from typing import Any, Union\nfrom urllib.parse import urlparse\n\nimport boto3\nimport json\nimport base64\n\nfrom core.tools"
  },
  {
    "path": "builtin_tools/aws/tools/opensearch_knn_search.yaml",
    "chars": 5376,
    "preview": "identity:\n  name: opensearch_retrieve\n  author: AWS\n  label:\n    en_US: OpenSearch Retrieve\n    zh_Hans: OpenSearch检索\n  "
  },
  {
    "path": "builtin_tools/aws/tools/s3_operator.py",
    "chars": 3272,
    "preview": "from typing import Any, Union\nfrom urllib.parse import urlparse\n\nimport boto3\n\nfrom core.tools.entities.tool_entities im"
  },
  {
    "path": "builtin_tools/aws/tools/s3_operator.yaml",
    "chars": 2245,
    "preview": "identity:\n  name: s3_operator\n  author: AWS\n  label:\n    en_US: AWS S3 Operator\n    zh_Hans: AWS S3 读写器\n    pt_BR: AWS S"
  },
  {
    "path": "builtin_tools/aws/tools/sagemaker_audio_to_text.py",
    "chars": 3240,
    "preview": "import json\nfrom typing import Any, Union\nimport boto3\nimport tempfile\nimport os\nfrom urllib.parse import urlparse\n\nfrom"
  },
  {
    "path": "builtin_tools/aws/tools/sagemaker_audio_to_text.yaml",
    "chars": 1333,
    "preview": "identity:\n  name: whisper_transcription\n  author: AWS\n  label:\n    en_US: Audio Transcription\n    zh_Hans: 语音转文字\n  icon:"
  },
  {
    "path": "builtin_tools/aws/tools/sagemaker_chinese_toxicity_detector.py",
    "chars": 2224,
    "preview": "import json\nfrom typing import Any, Union\n\nimport boto3\n\nfrom core.tools.entities.tool_entities import ToolInvokeMessage"
  },
  {
    "path": "builtin_tools/aws/tools/sagemaker_chinese_toxicity_detector.yaml",
    "chars": 1238,
    "preview": "identity:\n  name: chinese_toxicity_detector\n  author: AWS\n  label:\n    en_US: Chinese Toxicity Detector\n    zh_Hans: 中文有"
  },
  {
    "path": "builtin_tools/aws/tools/sagemaker_text_rerank.py",
    "chars": 2817,
    "preview": "import json\nimport operator\nfrom typing import Any, Union\n\nimport boto3  # type: ignore\n\nfrom core.tools.entities.tool_e"
  },
  {
    "path": "builtin_tools/aws/tools/sagemaker_text_rerank.yaml",
    "chars": 2450,
    "preview": "identity:\n  name: sagemaker_text_rerank\n  author: AWS\n  label:\n    en_US: SagemakerRerank\n    zh_Hans: Sagemaker重排序\n    "
  },
  {
    "path": "builtin_tools/aws/tools/sagemaker_tts.py",
    "chars": 4187,
    "preview": "import json\nfrom enum import Enum\nfrom typing import Any, Optional, Union\n\nimport boto3  # type: ignore\n\nfrom core.tools"
  },
  {
    "path": "builtin_tools/aws/tools/sagemaker_tts.yaml",
    "chars": 3872,
    "preview": "identity:\n  name: sagemaker_tts\n  author: AWS\n  label:\n    en_US: SagemakerTTS\n    zh_Hans: Sagemaker语音合成\n    pt_BR: Sag"
  },
  {
    "path": "builtin_tools/aws/tools/transcribe_asr.py",
    "chars": 14257,
    "preview": "import json\nimport logging\nimport os\nimport re\nimport time\nimport uuid\nfrom typing import Any, Union\nfrom urllib.parse i"
  },
  {
    "path": "builtin_tools/aws/tools/transcribe_asr.yaml",
    "chars": 5145,
    "preview": "identity:\n  name: transcribe_asr\n  author: AWS\n  label:\n    en_US: TranscribeASR\n    zh_Hans: Transcribe语音识别转录\n    pt_BR"
  },
  {
    "path": "dify.yaml",
    "chars": 7275,
    "preview": "Metadata:\n  AWS::CloudFormation::Interface:\n    ParameterGroups:\n      - Label:\n          default: VPC settings\n        "
  },
  {
    "path": "model_provider/sagemaker/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "model_provider/sagemaker/llm/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "model_provider/sagemaker/llm/llm.py",
    "chars": 19164,
    "preview": "import json\nimport logging\nimport re\nfrom collections.abc import Generator, Iterator\nfrom typing import Any, Optional, U"
  },
  {
    "path": "model_provider/sagemaker/rerank/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "model_provider/sagemaker/rerank/rerank.py",
    "chars": 6429,
    "preview": "import json\nimport logging\nimport operator\nfrom typing import Any, Optional\n\nimport boto3\n\nfrom core.model_runtime.entit"
  },
  {
    "path": "model_provider/sagemaker/sagemaker.py",
    "chars": 1297,
    "preview": "import logging\nimport uuid\nfrom typing import IO, Any\n\nfrom core.model_runtime.model_providers.__base.model_provider imp"
  },
  {
    "path": "model_provider/sagemaker/sagemaker.yaml",
    "chars": 5376,
    "preview": "provider: sagemaker\nlabel:\n  zh_Hans: Sagemaker\n  en_US: Sagemaker\nicon_small:\n  en_US: icon_s_en.png\nicon_large:\n  en_U"
  },
  {
    "path": "model_provider/sagemaker/speech2text/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "model_provider/sagemaker/speech2text/speech2text.py",
    "chars": 5473,
    "preview": "import json\nimport logging\nfrom typing import IO, Any, Optional\n\nimport boto3\n\nfrom core.model_runtime.entities.common_e"
  },
  {
    "path": "model_provider/sagemaker/text_embedding/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "model_provider/sagemaker/text_embedding/text_embedding.py",
    "chars": 6860,
    "preview": "import itertools\nimport json\nimport logging\nimport time\nfrom typing import Any, Optional\n\nimport boto3\n\nfrom core.entiti"
  },
  {
    "path": "model_provider/sagemaker/tts/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "model_provider/sagemaker/tts/tts.py",
    "chars": 10913,
    "preview": "import concurrent.futures\nimport copy\nimport json\nimport logging\nfrom enum import Enum\nfrom typing import Any, Optional\n"
  },
  {
    "path": "notebook/bge-embedding-m3-deploy.ipynb",
    "chars": 28914,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"7060c891-cebd-4011-b350-b7d1e70b40b2\",\n   \"metadata\": {\n    \"tag"
  },
  {
    "path": "notebook/bge-reranker-v2-m3-deploy.ipynb",
    "chars": 143306,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"ba7f6f98-70f2-4ca6-b999-eed03641ea87\",\n   \"metadata\": {},\n   \"so"
  },
  {
    "path": "notebook/byoc_qwen_rerank_deploy/README.md",
    "chars": 897,
    "preview": "# vLLM SageMaker Deployment(English)\n\nOpen the deploy_and_test.ipynb in the SageMaker notebook and execute it step by st"
  },
  {
    "path": "notebook/byoc_qwen_rerank_deploy/app/inference.py",
    "chars": 4665,
    "preview": "import os\nimport json\nfrom contextlib import asynccontextmanager\nfrom typing import Any, Dict, cast\n\nimport uvicorn\nimpo"
  },
  {
    "path": "notebook/byoc_qwen_rerank_deploy/app/serve",
    "chars": 317,
    "preview": "#!/bin/bash\n\n# Set the directory to check\nbase_dir=\"/opt/ml/code/\"\nexport SAGEMAKER_BIND_TO_PORT=${SAGEMAKER_BIND_TO_POR"
  },
  {
    "path": "notebook/byoc_qwen_rerank_deploy/build_and_push.sh",
    "chars": 1352,
    "preview": "#!/bin/bash\n# Get the ACCOUNT and REGION defined in the current configuration (default to us-west-2 if none defined)\nREP"
  },
  {
    "path": "notebook/byoc_qwen_rerank_deploy/deploy_and_test.ipynb",
    "chars": 15872,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"source\": [\n    \"# SageMaker VLLM"
  },
  {
    "path": "notebook/byoc_qwen_rerank_deploy/dockerfile",
    "chars": 278,
    "preview": "FROM vllm/vllm-openai:latest\n\nRUN pip install fastapi uvicorn\n\nCOPY ./app/inference.py /opt/ml/code/inference.py\nCOPY ./"
  },
  {
    "path": "notebook/cosyvoice/Dockerfile",
    "chars": 763,
    "preview": "FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime\n\nARG MODEL_NAME=CosyVoice-300M-SFT\nENV MODEL_DIR=pretrained_models/${"
  },
  {
    "path": "notebook/cosyvoice/README.md",
    "chars": 52,
    "preview": "## Install\n\nRun cosyvoice_deploy.ipynb step by step."
  },
  {
    "path": "notebook/cosyvoice/build_docker.sh",
    "chars": 1465,
    "preview": "model_name=$1\n\ncase \"$model_name\" in\n    \"CosyVoice-300M\" | \"CosyVoice-300M-SFT\" | \"CosyVoice-300M-Instruct\" | \"speech_k"
  },
  {
    "path": "notebook/cosyvoice/code/api_server.py",
    "chars": 2250,
    "preview": "# Set inference model\n# export MODEL_DIR=pretrained_models/CosyVoice-300M-Instruct\n# For development\n# fastapi dev api_s"
  },
  {
    "path": "notebook/cosyvoice/code/inference.py",
    "chars": 5770,
    "preview": "# -*- coding: utf-8 -*-\n# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n# Permission is hereby gra"
  },
  {
    "path": "notebook/cosyvoice/code/serve",
    "chars": 274,
    "preview": "#!/usr/bin/env python \nimport os\nimport uvicorn\n\n\nreload=os.environ.get(\"reload\", False)\n\nif __name__ == '__main__':\n   "
  },
  {
    "path": "notebook/cosyvoice/cosyvoice_deploy.ipynb",
    "chars": 12821,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"0e4fe47e-5e7a-4830-a3ea-0d452483a1e9\",\n   \"metadata\": {},\n   \"so"
  },
  {
    "path": "notebook/cosyvoice_china_region/Dockerfile",
    "chars": 638,
    "preview": "FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime\n\nARG MODEL_NAME=CosyVoice-300M-SFT\nENV MODEL_DIR=pretrained_models/${"
  },
  {
    "path": "notebook/cosyvoice_china_region/README.md",
    "chars": 52,
    "preview": "## Install\n\nRun cosyvoice_deploy.ipynb step by step."
  },
  {
    "path": "notebook/cosyvoice_china_region/build_docker.sh",
    "chars": 1465,
    "preview": "model_name=$1\n\ncase \"$model_name\" in\n    \"CosyVoice-300M\" | \"CosyVoice-300M-SFT\" | \"CosyVoice-300M-Instruct\" | \"speech_k"
  },
  {
    "path": "notebook/cosyvoice_china_region/code/api_server.py",
    "chars": 2250,
    "preview": "# Set inference model\n# export MODEL_DIR=pretrained_models/CosyVoice-300M-Instruct\n# For development\n# fastapi dev api_s"
  },
  {
    "path": "notebook/cosyvoice_china_region/code/inference.py",
    "chars": 5770,
    "preview": "# -*- coding: utf-8 -*-\n# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n# Permission is hereby gra"
  },
  {
    "path": "notebook/cosyvoice_china_region/code/serve",
    "chars": 274,
    "preview": "#!/usr/bin/env python \nimport os\nimport uvicorn\n\n\nreload=os.environ.get(\"reload\", False)\n\nif __name__ == '__main__':\n   "
  },
  {
    "path": "notebook/cosyvoice_china_region/cosyvoice_deploy.ipynb",
    "chars": 135000,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"0e4fe47e-5e7a-4830-a3ea-0d452483a1e9\",\n   \"metadata\": {},\n   \"so"
  },
  {
    "path": "notebook/deploy_lambda_yaml_to_json.md",
    "chars": 1121,
    "preview": "## Deploy LambdaYamlToJson tool\n\n### Step 0: Open AWS Lambda Console\n\nOpen [Console](https://console.aws.amazon.com/lamb"
  },
  {
    "path": "notebook/funasr-deploy-china-region.ipynb",
    "chars": 31344,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"7060c891-cebd-4011-b350-b7d1e70b40b2\",\n   \"metadata\": {\n    \"tag"
  },
  {
    "path": "notebook/funasr-deploy.ipynb",
    "chars": 30357,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"7060c891-cebd-4011-b350-b7d1e70b40b2\",\n   \"metadata\": {\n    \"tag"
  },
  {
    "path": "notebook/how_to_deploy.md",
    "chars": 750,
    "preview": "1. Access to Amazon SageMaker Notebook\n\n    ![notebook](../snapshots/notebook_entry.png)\n\n2. Clone the below notebooks\n "
  },
  {
    "path": "notebook/llm_sagemaker_deploy/README.md",
    "chars": 897,
    "preview": "# vLLM SageMaker Deployment(English)\n\nOpen the deploy_and_test.ipynb in the SageMaker notebook and execute it step by st"
  },
  {
    "path": "notebook/llm_sagemaker_deploy/app/serve",
    "chars": 1951,
    "preview": "#!/bin/bash\n\n\n# Set the directory to check\nbase_dir=\"/opt/ml/model/\"\nexport SAGEMAKER_BIND_TO_PORT=${SAGEMAKER_BIND_TO_P"
  },
  {
    "path": "notebook/llm_sagemaker_deploy/build_and_push.sh",
    "chars": 1461,
    "preview": "#!/bin/bash\nVLLM_REPO=${VLLM_REPO:-\"vllm/vllm-openai\"}\nVLLM_VERSION=${VLLM_VERSION:-\"latest\"}\nREPO_NAMESPACE=${REPO_NAME"
  },
  {
    "path": "notebook/llm_sagemaker_deploy/deploy_and_test.ipynb",
    "chars": 15360,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"source\": [\n    \"# SageMaker VLLM"
  },
  {
    "path": "notebook/llm_sagemaker_deploy/deploy_and_test_qwenvl.ipynb",
    "chars": 20258,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"tags\": []\n   },\n   \"source\": [\n    \"# SageMaker VLLM"
  },
  {
    "path": "notebook/llm_sagemaker_deploy/dockerfile",
    "chars": 1978,
    "preview": "ARG VLLM_REPO\nARG VLLM_VERSION\nFROM $VLLM_REPO:$VLLM_VERSION\n\n# 设置工作目录\nWORKDIR /app\n\n# 复制当前目录下的内容到容器内的/app\nCOPY app/ /ap"
  },
  {
    "path": "notebook/llm_sagemaker_deploy_sglang/README.md",
    "chars": 1159,
    "preview": "# SGLang SageMaker 部署方案(简化版)\n\n## 简介\n\n本方案利用 **SGLang 原生的 SageMaker API 支持**来部署模型。SGLang v0.2.13+ 已经内置了 `/ping` 和 `/invoca"
  },
  {
    "path": "notebook/llm_sagemaker_deploy_sglang/app/serve",
    "chars": 1023,
    "preview": "#!/bin/bash\n\necho \"==========================================\"\necho \"DIAGNOSTIC MODE - $(date)\"\necho \"=================="
  },
  {
    "path": "notebook/llm_sagemaker_deploy_sglang/build_and_push.sh",
    "chars": 1522,
    "preview": "#!/bin/bash\nSGLANG_REPO=${SGLANG_REPO:-\"lmsysorg/sglang\"}\nSGLANG_VERSION=${SGLANG_VERSION:-\"latest\"}\n\nREPO_NAMESPACE=${R"
  },
  {
    "path": "notebook/llm_sagemaker_deploy_sglang/deploy_and_test.ipynb",
    "chars": 42448,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# SageMaker SGLang endpoint example"
  },
  {
    "path": "notebook/llm_sagemaker_deploy_sglang/dockerfile",
    "chars": 589,
    "preview": "ARG SGLANG_REPO\nARG SGLANG_VERSION\nFROM ${SGLANG_REPO}:${SGLANG_VERSION}\n\n# 设置工作目录\nWORKDIR /app\n\n# 复制启动脚本\nCOPY app/serve"
  },
  {
    "path": "notebook/search_img_by_img/image_search.ipynb",
    "chars": 22073,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# 以图搜图\\n\",\n    \"\\n\",\n    \"本 Noteboo"
  },
  {
    "path": "notebook/whisper-deploy-china-region.ipynb",
    "chars": 24423,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"7060c891-cebd-4011-b350-b7d1e70b40b2\",\n   \"metadata\": {\n    \"tag"
  },
  {
    "path": "plugins/README.md",
    "chars": 205,
    "preview": "## How to Generate Plugin([Doc](https://docs.dify.ai/zh-hans/plugins/quick-start/develop-plugins))\n\n```\ndify plugin pack"
  },
  {
    "path": "plugins/aws_tools/.difyignore",
    "chars": 3415,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# Distribution / packaging\n.Python\nbuild/\ndev"
  },
  {
    "path": "plugins/aws_tools/.gitignore",
    "chars": 3380,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packagi"
  },
  {
    "path": "plugins/aws_tools/GUIDE.md",
    "chars": 6944,
    "preview": "## User Guide of how to develop a Dify Plugin\n\nHi there, looks like you have already created a Plugin, now let's get you"
  },
  {
    "path": "plugins/aws_tools/PRIVACY.md",
    "chars": 64,
    "preview": "## Privacy\n\n!!! Please fill in the privacy policy of the plugin."
  },
  {
    "path": "plugins/aws_tools/README.md",
    "chars": 2089,
    "preview": "## AWS Tools\n\n**Author:** aws  \n**Type:** Tool\n\n\n\n## Overview | 概述\n\nThe AWS Tools plugin provides a comprehensive set of"
  },
  {
    "path": "plugins/aws_tools/main.py",
    "chars": 148,
    "preview": "from dify_plugin import Plugin, DifyPluginEnv\n\nplugin = Plugin(DifyPluginEnv(MAX_REQUEST_TIMEOUT=120))\n\nif __name__ == '"
  },
  {
    "path": "plugins/aws_tools/manifest.yaml",
    "chars": 805,
    "preview": "version: 0.0.20\ntype: plugin\nauthor: langgenius\nname: aws_tools\nlabel:\n  en_US: AWS Tools\n  ja_JP: AWS Tools\n  zh_Hans: "
  },
  {
    "path": "plugins/aws_tools/provider/aws_tools.py",
    "chars": 448,
    "preview": "from typing import Any\n\nfrom dify_plugin import ToolProvider\nfrom dify_plugin.errors.tool import ToolProviderCredentialV"
  },
  {
    "path": "plugins/aws_tools/provider/aws_tools.yaml",
    "chars": 1093,
    "preview": "identity:\n  author: aws\n  name: aws_tools\n  label:\n    en_US: AWS Tools\n    zh_Hans: 亚马逊云科技工具集\n    pt_BR: AWS Tools\n  de"
  },
  {
    "path": "plugins/aws_tools/provider/utils.py",
    "chars": 2829,
    "preview": "import boto3\nimport json\nfrom botocore.exceptions import ClientError\nfrom typing import Optional, Dict, Any, Union\n\n\ncla"
  },
  {
    "path": "plugins/aws_tools/requirements.txt",
    "chars": 183,
    "preview": "dify_plugin>=0.4.2,<0.5.0\nboto3~=1.40.45\nopensearch-py~=2.8.0\njieba~=0.42.1\nnltk~=3.9.1\nsacrebleu~=2.5.1\nPillow~=11.3.0\n"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore-browser-session-manager.py",
    "chars": 3498,
    "preview": "import json\nimport time\nimport logging\nfrom collections.abc import Generator\nfrom typing import Any, Optional, Dict\n\nimp"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore-browser-session-manager.yaml",
    "chars": 3164,
    "preview": "identity:\n  name: \"agentcore-browser-session-manager\"\n  author: \"aws\"\n  label:\n    en_US: \"AgentCore Browser Session Man"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore-browser-tool.py",
    "chars": 20518,
    "preview": "import json\nimport time\nimport base64\nimport asyncio\nimport nest_asyncio\nfrom collections.abc import Generator\nfrom typi"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore-browser-tool.yaml",
    "chars": 8024,
    "preview": "identity:\n  name: \"agentcore-browser-tool\"\n  author: \"aws\"\n  label:\n    en_US: \"AgentCore Browser Tool\"\n    zh_Hans: \"Ag"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore_code_interpreter.py",
    "chars": 4951,
    "preview": "from collections.abc import Generator\nfrom typing import Any\nfrom dify_plugin import Tool\nfrom dify_plugin.entities.tool"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore_code_interpreter.yaml",
    "chars": 3568,
    "preview": "identity:\n  name: \"agentcore_code_interpreter\"\n  author: \"aws\"\n  label:\n    en_US: \"AgentCore Code Interpreter\"\n    zh_H"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore_memory.py",
    "chars": 13871,
    "preview": "import json\nimport logging\nfrom collections.abc import Generator\nfrom typing import Any, Dict\nfrom dify_plugin import To"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore_memory.yaml",
    "chars": 5864,
    "preview": "identity:\n  name: agentcore_memory\n  author: AWS\n  label:\n    en_US: AgentCore Memory\n    zh_Hans: AgentCore 记忆\n    pt_B"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore_memory_search.py",
    "chars": 7514,
    "preview": "import json\nimport logging\nfrom collections.abc import Generator\nfrom typing import Any, Dict\nfrom dify_plugin import To"
  },
  {
    "path": "plugins/aws_tools/tools/agentcore_memory_search.yaml",
    "chars": 4354,
    "preview": "identity:\n  name: agentcore_memory_search\n  author: AWS\n  label:\n    en_US: AgentCore Memory Search\n    zh_Hans: AgentCo"
  },
  {
    "path": "plugins/aws_tools/tools/apply_guardrail.py",
    "chars": 3887,
    "preview": "import json\nimport logging\nfrom typing import Any, Union\nfrom collections.abc import Generator\nfrom pydantic import Base"
  },
  {
    "path": "plugins/aws_tools/tools/apply_guardrail.yaml",
    "chars": 3755,
    "preview": "identity:\n  name: apply_guardrail\n  author: AWS\n  label:\n    en_US: Content Moderation Guardrails\n    zh_Hans: 内容审查护栏\nde"
  },
  {
    "path": "plugins/aws_tools/tools/bedrock_retrieve.py",
    "chars": 7963,
    "preview": "import json\nimport operator\nfrom typing import Any, Optional, Union\nfrom collections.abc import Generator\n\nimport boto3\n"
  },
  {
    "path": "plugins/aws_tools/tools/bedrock_retrieve.yaml",
    "chars": 5045,
    "preview": "identity:\n  name: bedrock_retrieve\n  author: AWS\n  label:\n    en_US: Bedrock Retrieve\n    zh_Hans: Bedrock检索\n    pt_BR: "
  },
  {
    "path": "plugins/aws_tools/tools/bedrock_retrieve_and_generate.py",
    "chars": 7177,
    "preview": "import json\nfrom typing import Any\nfrom collections.abc import Generator\n\nimport boto3\n\nfrom dify_plugin import Tool\nfro"
  },
  {
    "path": "plugins/aws_tools/tools/bedrock_retrieve_and_generate.yaml",
    "chars": 4349,
    "preview": "identity:\n  name: bedrock_retrieve_and_generate\n  author: AWS\n  label:\n    en_US: Bedrock Retrieve and Generate\n    zh_H"
  },
  {
    "path": "plugins/aws_tools/tools/dynamodb_manager.py",
    "chars": 5785,
    "preview": "import json\nfrom typing import Any\nimport boto3\nfrom botocore.exceptions import ClientError\nfrom collections.abc import "
  },
  {
    "path": "plugins/aws_tools/tools/dynamodb_manager.yaml",
    "chars": 4295,
    "preview": "identity:\n  name: dynamodb_manager\n  author: AWS\n  label:\n    en_US: DynamoDB Manager\n    zh_Hans: DynamoDB 管理器\ndescript"
  },
  {
    "path": "plugins/aws_tools/tools/extract_frame.py",
    "chars": 4306,
    "preview": "from typing import Any, Generator\nimport os\nimport shutil\nimport requests\nfrom PIL import Image\n\nfrom dify_plugin import"
  },
  {
    "path": "plugins/aws_tools/tools/extract_frame.yaml",
    "chars": 1278,
    "preview": "identity:\n  name: extract_frame\n  author: AWS\n  label:\n    en_US: ExtractFrame\n    zh_Hans: 抽帧工具\n    pt_BR: ExtractFrame"
  },
  {
    "path": "plugins/aws_tools/tools/lambda_translate_utils.py",
    "chars": 3132,
    "preview": "import json\nfrom typing import Any, Union\nfrom collections.abc import Generator\n\nimport boto3  # type: ignore\n\nfrom dify"
  },
  {
    "path": "plugins/aws_tools/tools/lambda_translate_utils.yaml",
    "chars": 4042,
    "preview": "identity:\n  name: lambda_translate_utils\n  author: AWS\n  label:\n    en_US: TranslateTool\n    zh_Hans: 翻译工具\n    pt_BR: Tr"
  },
  {
    "path": "plugins/aws_tools/tools/lambda_yaml_to_json.py",
    "chars": 2336,
    "preview": "import json\nimport logging\nfrom typing import Any, Union\nfrom collections.abc import Generator\n\nimport boto3  # type: ig"
  },
  {
    "path": "plugins/aws_tools/tools/lambda_yaml_to_json.yaml",
    "chars": 1426,
    "preview": "identity:\n  name: lambda_yaml_to_json\n  author: AWS\n  label:\n    en_US: LambdaYamlToJson\n    zh_Hans: LambdaYamlToJson\n "
  },
  {
    "path": "plugins/aws_tools/tools/nova_canvas.py",
    "chars": 15849,
    "preview": "import base64\nimport json\nimport logging\nimport re\nfrom datetime import datetime\nfrom typing import Any, Union\nfrom urll"
  },
  {
    "path": "plugins/aws_tools/tools/nova_canvas.yaml",
    "chars": 5379,
    "preview": "identity:\n  name: nova_canvas\n  author: AWS\n  label:\n    en_US: AWS Bedrock Nova Canvas\n    zh_Hans: AWS Bedrock Nova Ca"
  },
  {
    "path": "plugins/aws_tools/tools/nova_reel.py",
    "chars": 16892,
    "preview": "import base64\nimport logging\nimport time\nfrom io import BytesIO\nfrom typing import Any, Optional, Union\nfrom urllib.pars"
  },
  {
    "path": "plugins/aws_tools/tools/nova_reel.yaml",
    "chars": 3296,
    "preview": "identity:\n  name: nova_reel\n  author: AWS\n  label:\n    en_US: AWS Bedrock Nova Reel\n    zh_Hans: AWS Bedrock Nova Reel\n "
  },
  {
    "path": "plugins/aws_tools/tools/opensearch_knn_search.py",
    "chars": 5221,
    "preview": "from typing import Any, Union\nfrom urllib.parse import urlparse\n\nimport boto3\nimport json\nimport base64\nfrom collections"
  },
  {
    "path": "plugins/aws_tools/tools/opensearch_knn_search.yaml",
    "chars": 5432,
    "preview": "identity:\n  name: opensearch_retrieve\n  author: aws\n  label:\n    en_US: OpenSearch Retrieve\n    zh_Hans: OpenSearch检索\n  "
  },
  {
    "path": "plugins/aws_tools/tools/s3_operator.py",
    "chars": 3850,
    "preview": "from typing import Any, Union\nfrom urllib.parse import urlparse\nimport mimetypes\n\nimport boto3\n\n# from core.tools.entiti"
  },
  {
    "path": "plugins/aws_tools/tools/s3_operator.yaml",
    "chars": 2277,
    "preview": "identity:\n  name: s3_operator\n  author: AWS\n  label:\n    en_US: AWS S3 Operator\n    zh_Hans: AWS S3 读写器\n    pt_BR: AWS S"
  },
  {
    "path": "plugins/aws_tools/tools/sagemaker_chinese_toxicity_detector.py",
    "chars": 2179,
    "preview": "import json\nfrom typing import Any, Union\nfrom collections.abc import Generator\n\nimport boto3\n\nfrom dify_plugin import T"
  },
  {
    "path": "plugins/aws_tools/tools/sagemaker_chinese_toxicity_detector.yaml",
    "chars": 1311,
    "preview": "identity:\n  name: chinese_toxicity_detector\n  author: AWS\n  label:\n    en_US: Chinese Toxicity Detector\n    zh_Hans: 中文有"
  },
  {
    "path": "plugins/aws_tools/tools/sagemaker_text_rerank.py",
    "chars": 2817,
    "preview": "import json\nimport operator\nfrom typing import Any, Union\nfrom collections.abc import Generator\n\nimport boto3\n\nfrom dify"
  },
  {
    "path": "plugins/aws_tools/tools/sagemaker_text_rerank.yaml",
    "chars": 2509,
    "preview": "identity:\n  name: sagemaker_text_rerank\n  author: AWS\n  label:\n    en_US: SagemakerRerank\n    zh_Hans: Sagemaker重排序\n    "
  },
  {
    "path": "plugins/aws_tools/tools/sagemaker_tts.py",
    "chars": 4125,
    "preview": "import json\nfrom enum import Enum\nfrom typing import Any, Optional, Union\nfrom collections.abc import Generator\n\nimport "
  },
  {
    "path": "plugins/aws_tools/tools/sagemaker_tts.yaml",
    "chars": 3923,
    "preview": "identity:\n  name: sagemaker_tts\n  author: AWS\n  label:\n    en_US: SagemakerTTS\n    zh_Hans: Sagemaker语音合成\n    pt_BR: Sag"
  },
  {
    "path": "plugins/aws_tools/tools/transcribe_asr.py",
    "chars": 14590,
    "preview": "import json\nimport logging\nimport os\nimport re\nimport time\nimport uuid\nimport requests\nfrom requests.exceptions import R"
  },
  {
    "path": "plugins/aws_tools/tools/transcribe_asr.yaml",
    "chars": 6083,
    "preview": "identity:\n  name: transcribe_asr\n  author: AWS\n  label:\n    en_US: TranscribeASR\n    zh_Hans: Transcribe语音识别转录\n    pt_BR"
  },
  {
    "path": "plugins/aws_tools/tools/translation_evaluator.py",
    "chars": 3907,
    "preview": "import json\nimport operator\nfrom typing import Any, Union\nfrom collections.abc import Generator\n\nimport nltk\nimport sacr"
  },
  {
    "path": "plugins/aws_tools/tools/translation_evaluator.yaml",
    "chars": 1893,
    "preview": "identity:\n  name: translation_evaluator\n  author: AWS\n  label:\n    en_US: TranslationEvaluator\n    zh_Hans: 翻译质量评估\n    p"
  },
  {
    "path": "plugins/bedrock/.difyignore",
    "chars": 100,
    "preview": "venv/\n.venv/\n__pycache__/\n*.pyc\n*.py[cod]\n*$py.class\n.env\n.DS_Store\n*.so\ntest_*\n.pytest_cache/\n.git/"
  },
  {
    "path": "plugins/bedrock/GUIDE.md",
    "chars": 6944,
    "preview": "## User Guide of how to develop a Dify Plugin\n\nHi there, looks like you have already created a Plugin, now let's get you"
  },
  {
    "path": "plugins/bedrock/PRIVACY.md",
    "chars": 64,
    "preview": "## Privacy\n\n!!! Please fill in the privacy policy of the plugin."
  },
  {
    "path": "plugins/bedrock/README.md",
    "chars": 2216,
    "preview": "## Amazon Bedrock\n\n**Author:** aws  \n**Type:** Model Provider\n\n\n\n## Overview | 概述\n\nThe [Amazon Bedrock](https://aws.amaz"
  },
  {
    "path": "plugins/bedrock/main.py",
    "chars": 231,
    "preview": "from dify_plugin import Plugin, DifyPluginEnv\nimport logging\n\nlogger = logging.getLogger(__name__)\nlogger.setLevel(loggi"
  },
  {
    "path": "plugins/bedrock/manifest.yaml",
    "chars": 811,
    "preview": "version: 0.0.59\ntype: plugin\nauthor: langgenius\nname: bedrock\nlabel:\n  en_US: Amazon Bedrock\n  ja_JP: Amazon Bedrock\n  z"
  },
  {
    "path": "plugins/bedrock/models/llm/_position.yaml",
    "chars": 82,
    "preview": "- anthropic-claude\n- amazon-nova\n- cohere\n- meta-llama\n- mistral\n- ai21\n- deepseek"
  },
  {
    "path": "plugins/bedrock/models/llm/ai21.yaml",
    "chars": 674,
    "preview": "model: ai21\nlabel:\n  en_US: AI21 Labs\nicon: icon_s_en.svg\nmodel_type: llm\nmodel_properties:\n  mode: completion\n  context"
  },
  {
    "path": "plugins/bedrock/models/llm/amazon-nova.yaml",
    "chars": 2860,
    "preview": "model: amazon nova\nlabel:\n  en_US: Amazon Nova\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - tool-"
  },
  {
    "path": "plugins/bedrock/models/llm/anthropic-claude.yaml",
    "chars": 5135,
    "preview": "model: anthropic claude\nlabel:\n  en_US: Anthropic Claude\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought"
  },
  {
    "path": "plugins/bedrock/models/llm/cache_config.py",
    "chars": 3494,
    "preview": "\"\"\"\nConfiguration for Bedrock prompt cache feature\n\"\"\"\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n# Models th"
  },
  {
    "path": "plugins/bedrock/models/llm/cohere.yaml",
    "chars": 1895,
    "preview": "model: cohere\nlabel:\n  en_US: Cohere\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - tool-call\n  - s"
  },
  {
    "path": "plugins/bedrock/models/llm/deepseek.yaml",
    "chars": 2187,
    "preview": "model: deepseek\nlabel:\n  en_US: DeepSeek\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - vision\n  - "
  },
  {
    "path": "plugins/bedrock/models/llm/llm.py",
    "chars": 80115,
    "preview": "# standard import\nimport base64\nimport json\nimport logging\nfrom collections.abc import Generator\nfrom typing import Opti"
  },
  {
    "path": "plugins/bedrock/models/llm/meta-llama.yaml",
    "chars": 1320,
    "preview": "model: meta\nlabel:\n  en_US: Meta Llama\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - tool-call\n  - agent-thought\nmod"
  },
  {
    "path": "plugins/bedrock/models/llm/mistral.yaml",
    "chars": 795,
    "preview": "model: mistral\nlabel:\n  en_US: Mistral AI\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - tool-call\n  - agent-thought\n"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/claude-3-5-haiku.yaml",
    "chars": 2816,
    "preview": "model: claude-3-5-haiku\nlabel:\n  en_US: Claude 3.5 Haiku\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/claude-3-5-sonnet.yaml",
    "chars": 2818,
    "preview": "model: claude-3-5-sonnet\nlabel:\n  en_US: Claude 3.5 Sonnet\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thoug"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/claude-3-7-sonnet.yaml",
    "chars": 2818,
    "preview": "model: claude-3-7-sonnet\nlabel:\n  en_US: Claude 3.7 Sonnet\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thoug"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/claude-3-haiku.yaml",
    "chars": 2816,
    "preview": "model: claude-3-haiku\nlabel:\n  en_US: Claude 3 Haiku\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  -"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/claude-3-opus.yaml",
    "chars": 2810,
    "preview": "model: claude-3-opus\nlabel:\n  en_US: Claude 3 Opus\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - v"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/claude-3-sonnet.yaml",
    "chars": 2814,
    "preview": "model: claude-3-sonnet\nlabel:\n  en_US: Claude 3 Sonnet\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n "
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/claude-4-opus.yaml",
    "chars": 2812,
    "preview": "model: claude-4-opus\nlabel:\n  en_US: Claude 4.0 Opus\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  -"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/claude-4-sonnet.yaml",
    "chars": 3227,
    "preview": "model: claude-4-sonnet\nlabel:\n  en_US: Claude 4.0 Sonnet\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/cohere-command-light.yaml",
    "chars": 1505,
    "preview": "model: cohere-command-light\nlabel:\n  en_US: Cohere Command Light\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/cohere-command-r.yaml",
    "chars": 1497,
    "preview": "model: cohere-command-r\nlabel:\n  en_US: Cohere Command R\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/cohere-command-rplus.yaml",
    "chars": 1500,
    "preview": "model: cohere-command-rplus\nlabel:\n  en_US: Cohere Command R+\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-th"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/cohere-command.yaml",
    "chars": 1491,
    "preview": "model: cohere-command\nlabel:\n  en_US: Cohere Command\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  -"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/nova-lite.yaml",
    "chars": 2428,
    "preview": "model: nova-lite\nlabel:\n  en_US: Nova Lite\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - tool-call"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/nova-micro.yaml",
    "chars": 2430,
    "preview": "model: nova-micro\nlabel:\n  en_US: Nova Micro\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - tool-ca"
  },
  {
    "path": "plugins/bedrock/models/llm/model_configurations/nova-pro.yaml",
    "chars": 2424,
    "preview": "model: nova-pro\nlabel:\n  en_US: Nova Pro\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - tool-call\n "
  },
  {
    "path": "plugins/bedrock/models/llm/model_ids.py",
    "chars": 4870,
    "preview": "\"\"\"\nBedrock model IDs configuration file.\nThis file maintains the mapping between model names and their corresponding Be"
  },
  {
    "path": "plugins/bedrock/models/llm/openai.yaml",
    "chars": 1945,
    "preview": "model: openai\nlabel:\n  en_US: OpenAI\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - tool-call\n  - s"
  },
  {
    "path": "plugins/bedrock/models/llm/qwen.yaml",
    "chars": 1988,
    "preview": "model: qwen\nlabel:\n  en_US: Qwen\nicon: icon_s_en.svg\nmodel_type: llm\nfeatures:\n  - agent-thought\n  - tool-call\n  - strea"
  },
  {
    "path": "plugins/bedrock/models/rerank/amazon.rerank-v1.yaml",
    "chars": 84,
    "preview": "model: amazon.rerank-v1:0\nmodel_type: rerank\nmodel_properties:\n  context_size: 5120\n"
  },
  {
    "path": "plugins/bedrock/models/rerank/cohere.rerank-v3-5.yaml",
    "chars": 86,
    "preview": "model: cohere.rerank-v3-5:0\nmodel_type: rerank\nmodel_properties:\n  context_size: 5120\n"
  },
  {
    "path": "plugins/bedrock/models/rerank/model_ids.py",
    "chars": 1283,
    "preview": "\"\"\"\nBedrock rerank model IDs configuration file.\nThis file maintains the mapping between model names and their correspon"
  },
  {
    "path": "plugins/bedrock/models/rerank/rerank.py",
    "chars": 11584,
    "preview": "from typing import Optional\nimport logging\nimport json\n\nfrom botocore.exceptions import ClientError\n\nfrom dify_plugin.en"
  },
  {
    "path": "plugins/bedrock/models/text_embedding/amazon.nova-2-multimodal-embeddings-v1.yaml",
    "chars": 214,
    "preview": "model: amazon.nova-2-multimodal-embeddings-v1:0\nmodel_type: text-embedding\nmodel_properties:\n  context_size: 8192\n  max_"
  },
  {
    "path": "plugins/bedrock/models/text_embedding/amazon.titan-embed-text-v1.yaml",
    "chars": 160,
    "preview": "model: amazon.titan-embed-text-v1\nmodel_type: text-embedding\nmodel_properties:\n  context_size: 8192\npricing:\n  input: '0"
  },
  {
    "path": "plugins/bedrock/models/text_embedding/amazon.titan-embed-text-v2.yaml",
    "chars": 164,
    "preview": "model: amazon.titan-embed-text-v2:0\nmodel_type: text-embedding\nmodel_properties:\n  context_size: 8192\npricing:\n  input: "
  },
  {
    "path": "plugins/bedrock/models/text_embedding/cohere.embed-english-v3.yaml",
    "chars": 194,
    "preview": "model: cohere.embed-english-v3\nlabel:\n  en_US: Cohere Embed 3 English\nmodel_type: text-embedding\nmodel_properties:\n  con"
  },
  {
    "path": "plugins/bedrock/models/text_embedding/cohere.embed-multilingual-v3.yaml",
    "chars": 204,
    "preview": "model: cohere.embed-multilingual-v3\nlabel:\n  en_US: Cohere Embed 3 Multilingual\nmodel_type: text-embedding\nmodel_propert"
  },
  {
    "path": "plugins/bedrock/models/text_embedding/model_ids.py",
    "chars": 1564,
    "preview": "\"\"\"\nBedrock text embedding model IDs configuration file.\nThis file maintains the mapping between model names and their c"
  },
  {
    "path": "plugins/bedrock/models/text_embedding/text_embedding.py",
    "chars": 20705,
    "preview": "import json\nimport logging\nimport time\nimport tiktoken\nfrom typing import Optional\nfrom botocore.exceptions import (\n   "
  },
  {
    "path": "plugins/bedrock/provider/bedrock.py",
    "chars": 4355,
    "preview": "import logging\nfrom collections.abc import Mapping\nimport boto3\nfrom botocore.exceptions import ClientError\n\nfrom dify_p"
  },
  {
    "path": "plugins/bedrock/provider/bedrock.yaml",
    "chars": 10875,
    "preview": "provider: bedrock\nlabel:\n  en_US: Amazon Bedrock\ndescription:\n  en_US: Bedrock LLM Model \nbackground: \"#FCFDFF\"\nhelp:\n  "
  },
  {
    "path": "plugins/bedrock/provider/get_bedrock_client.py",
    "chars": 2663,
    "preview": "from collections.abc import Mapping\n\nimport os\nimport boto3\nfrom botocore.config import Config\n\nfrom dify_plugin.errors."
  },
  {
    "path": "plugins/bedrock/requirements.txt",
    "chars": 50,
    "preview": "dify_plugin==0.7.0\nboto3~=1.40.70\ntiktoken~=0.8.0\n"
  },
  {
    "path": "plugins/bedrock/utils/__init__.py",
    "chars": 34,
    "preview": "# Utils package for Bedrock models"
  },
  {
    "path": "plugins/bedrock/utils/inference_profile.py",
    "chars": 7524,
    "preview": "\"\"\"\nShared utility functions for Bedrock inference profiles\n\"\"\"\nimport logging\nimport threading\nimport time\nfrom typing "
  },
  {
    "path": "plugins/sagemaker/.difyignore",
    "chars": 3415,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# Distribution / packaging\n.Python\nbuild/\ndev"
  },
  {
    "path": "plugins/sagemaker/.gitignore",
    "chars": 3380,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packagi"
  },
  {
    "path": "plugins/sagemaker/GUIDE.md",
    "chars": 6944,
    "preview": "## User Guide of how to develop a Dify Plugin\n\nHi there, looks like you have already created a Plugin, now let's get you"
  }
]

// ... and 51 more files (download for full content)

About this extraction

This page contains the full source code of the aws-samples/dify-aws-tool GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 251 files (14.5 MB), approximately 550.2k tokens, and a symbol index with 431 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!