Conseils pour développer des plugins Dify avec Cursor

Vous êtes un développeur senior qui peut m'aider à développer Dify Plugin Tool, qui est un AI Agent Tool qui peut être utilisé sur l'AI Agent Development Tool, Dify. Vous allez suivre les instructions ci-dessous pour m'aider à construire un Plugin Tool appelé { }. L'auteur de cet outil est { }. L'auteur de cet outil est { }. Cet outil doit avoir les fonctionnalités de { }. Assurez-vous que vous modifiez le dossier du projet existant : { } et la structure du fichier. Le plus important est l'indentation et la structure du fichier yaml. Le plus important est que l'indentation et le formatage du fichier yaml suivent strictement les exemples du fichier yaml. Une fois que l'outil de plugin est prêt, configurez venv et installez tous les pré-requis sous le plugin. Une fois que l'outil de plugin est prêt, configurez venv et installez tous les pré-requis dans le répertoire du plugin. Vous ne devez changer que les fichiers que les instructions vous ont demandé de changer. Ne changez rien d'autre, par exemple le fichier env.example .
Avant d'appliquer quoi que ce soit, je veux que vous {lisiez la documentation de l'accès à l'API de l'outil}/{comprendre quelle est la fonctionnalité de l'outil, quelles sont les données d'entrée de l'outil, quelles sont ses fonctionnalités et quels sont les résultats que nous obtenons}.
L'échafaudage de Dify Plugin Tool est listé ci-dessous, et vous devez suivre les instructions suivantes pour m'aider à construire l'outil.
your_plugin/ ├── _assets/ # Répertoire pour les actifs visuels utilisés dans les listes de la place de marché │ └── icon.svg # Icône du plugin affichée dans l'interface utilisateur de la place de marché Dify marketplace │ ├── provider/ # Configuration et validation de l'authentification │ ├── your_plugin.py Classe # qui hérite de ToolProvider ; valide les informations d'identification │ ├── your_plugin.py Classe # qui hérite de ToolProvider. valide les informations d'identification │ └── your_plugin.yaml # Configure les champs de l'interface utilisateur d'authentification, les étiquettes et le texte d'aide │ ├── tools/ # Fichiers de mise en œuvre de l'outil │ ├── your_plugin.py your_plugin.py # Classe qui hérite de Tool ; met en œuvre les fonctionnalités de l'API │ └── your_plugin.yaml # Définit les paramètres de l'outil, les descriptions │ ├── .diftyignore # Liste les fichiers à exclure lors de la publication sur la place de marché │ ├─── .env.example # Modèle pour les variables d'environnement nécessaires aux tests │ # nécessaires pour les tests │ # Contient l'espace réservé REMOTE_INSTALL_KEY │ ├── .gitignore # Fichier standard Git ignore pour le contrôle de version │ ├── [ GUIDE.md]() # Instructions d'utilisation détaillées montrées aux utilisateurs sur la place de marché │ ├─── [main.py]() # Point d'entrée pour les tests locaux via python -m main test │ # Ne doit généralement pas être modifié │ ├── manifest.yaml # Métadonnées de base pour la liste de la place de marché : │ # - Numéro de version │ # - Compatibilité info │ # - Capacités du plugin │ # - Catégorisation de la place de marché │ ├── [PRIVACY.md]() # Politique de confidentialité affichée sur la place de marché │ ├─── [README .md]() # Documentation générale et vue d'ensemble pour les développeurs │ └── requirements.txt # Dépendances du paquet Python requises par le plugin
1. comment éditer manifest.yaml
Vous êtes chargé de créer le fichier manifest.yaml pour un plugin Dify. Ce fichier est le fichier de configuration central qui décrit l'ensemble de votre plugin pour la place de marché de Dify. Ce fichier est le fichier de configuration central qui décrit l'ensemble de votre plugin pour la place de marché de Dify. Je vais vous guider dans la création de ce fichier, en vous expliquant quelles parties affectent l'apparence de votre plugin sur la place de marché.
Objet du dossier
Le fichier manifest.yaml sert de fichier de configuration principal pour votre plugin, définissant.
Informations de base sur les plugins affichées dans le Marché
Version et ressources nécessaires
Permissions nécessaires à votre plugin
Références aux fournisseurs d'outils
Exemple de mise en œuvre (Dropbox)
Voici à quoi ressemble le fichier manifest.yaml d'un outil Dropbox.
version : 0.0.1
type : plugin
auteur : langgenius
nom : dropbox
étiquette.
fr_US : Dropbox
ja_JP : Dropbox
zh_Hans : Dropbox
pt_BR : Dropbox
zh_Hant : Dropbox
description.
fr_US : Interagir avec les fichiers et les dossiers Dropbox. Permet de lister, rechercher, charger, télécharger et gérer des fichiers.
ja_JP : Dropbox のファイルとフォルダ を操作します。 La liste des fichiers, la recherche, l'application, le téléchargement et la gestion sont possibles.
zh_Hans : Interagit avec les fichiers et dossiers Dropbox. Permet de lister, rechercher, charger, télécharger et gérer des fichiers.
pt_BR : Interaja com arquivos e pastas do Dropbox. Permite listar, pesquisar, fazer upload, download e gerenciar arquivos.
zh_Hant : Interagit avec les fichiers et dossiers Dropbox. Liste, recherche, chargement, téléchargement et gestion des fichiers.
icône : icon.svg
ressources.
mémoire : 268435456
autorisation.
l'outil.
activé : vrai
modèle.
activé : vrai
llm : vrai
text_embedding : false
rerank : faux
tts : faux
speech2text : false
modération : faux
stockage.
activé : vrai
taille : 1048576
plugins.
des outils.
- provider/dropbox.yaml
méta.
version : 0.0.1
arch.
- amd64
- arm64
coureur.
langage : python
version : "3.12"
point d'entrée : principal
created_at: 2025-04-03T17:41:08.159756+08:00
vie privée : PRIVACY.md
Principaux éléments influençant l'affichage sur le marché
Informations de base (figurant dans la liste des plugins).
version : le numéro de version de votre plugin
auteur : le nom de votre organisation est affiché sur la place de marché
name : Nom interne de votre plugin
label : Affichage du nom dans différentes langues
created_at : Heure de création au format RFC3339 (doit être dans le passé)
icon : Chemin d'accès à l'icône de votre plugin
description : description complète dans différentes langues
tags : Catégories pour votre plugin. Vous ne pouvez définir qu'un seul tag à la fois (actuellement, les tags ne peuvent contenir que 'search', 'image', 'videos', 'weather', 'finance', 'design', ' travel', 'social', 'news', 'medical', 'productivity', 'education', 'business', 'entertainment', 'utilities' ou 'other')
Besoins en ressources (indiqués dans la section des besoins).
resource.memory : Utilisation maximale de la mémoire en octets (par exemple, 1048576 = 1MB)
resource.permission : Permissions requises pour votre plugin
Références du plugin.
plugins.tools : Chemin d'accès au(x) fichier(s) YAML de votre fournisseur
Impact sur le marché
En regardant la capture d'écran de Marketplace que vous avez fournie, vous pouvez voir comment ces champs apparaissent.
Le nom, l'icône et la description du plugin apparaissent en haut de la page.
Le nom de l'auteur et le numéro de version sont indiqués sous la description
Les tags apparaissent dans la section "TAGS
Les exigences en matière de mémoire sont indiquées dans la section "EXIGENCES".
Notes importantes
La plupart des champs peuvent être laissés tels qu'ils ont été initialement configurés dans le modèle, en particulier.
type : Conserver comme "plugin"
section méta : conserver les valeurs par défaut
resource.permission : Ne changez que si votre plugin a besoin de permissions spécifiques.
Champs à personnaliser.
version : le numéro de version de votre plugin
auteur : Nom de votre organisation
name : Un identifiant unique pour votre plugin
label : Le nom affiché dans les différentes langues
description : une description claire de ce que fait votre plugin
tags : Catégories pertinentes pour votre plugin
plugins.tools : Chemin d'accès au(x) fichier(s) YAML de votre fournisseur
Pour créer votre propre fichier manifest.yaml, commencez par le modèle et personnalisez les champs qui affectent la façon dont votre plugin apparaît dans le Marketplace. La clé est de fournir des informations claires et concises qui aident les utilisateurs à comprendre ce que fait votre plugin. Cependant, tout ceci étant dit, vous devriez toujours laisser le fichier manifest.yaml tel quel, car tout est configuré lors de l'initialisation. tel quel, car tout est configuré lors de l'initialisation.
2) Comment éditer provider/your_plugin.yaml ?
Vous êtes chargé de créer le fichier YAML de configuration du fournisseur pour un plugin Dify. Ce fichier définit les informations d'identification requises pour votre service et la manière dont il est utilisé. Je vais vous guider pas à pas dans la création de ce fichier, en utilisant Google Search comme exemple.
Objet du dossier
Le fichier YAML du fournisseur (your_plugin.yaml) définit.
Quelles informations d'identification les utilisateurs doivent-ils fournir pour utiliser votre service ?
Comment ces informations d'identification sont collectées et affichées dans l'interface utilisateur ?
Quels sont les outils inclus dans votre plugin ?
Le fichier Python qui valide ces informations d'identification
Composants requis
section identité : métadonnées de base pour votre plugin (obligatoire mais n'affecte pas l'apparence de la place de marché)
section credentials_for_provider : définit les informations d'authentification que les utilisateurs doivent fournir
section outils : liste les fichiers de configuration des outils inclus
section supplémentaire : spécifie le fichier Python utilisé pour la validation des informations d'identification
Exemple de mise en œuvre
Voici à quoi ressemble le fichier YAML du fournisseur de l'outil Dropbox.
l'identité.
auteur : lcandy
nom : dropbox
étiquette.
fr_US : Dropbox
zh_Hans : Dropbox
pt_BR : Dropbox
ja_JP : Dropbox
zh_Hant : Dropbox
description.
fr_US : Interagir avec les fichiers et dossiers Dropbox
zh_Hans : Interagir avec les fichiers et dossiers Dropbox
pt_BR : Interaction avec les archives et les données de Dropbox
ja_jp : Dropbox のファイルとフォルダを操作します
zh_Hant : Interagir avec les fichiers et dossiers Dropbox
icône : icon.svg
informations d'identification pour le fournisseur.
access_token.
type : secret-input
obligatoire : true
étiquette.
fr_US : Accès Jeton
zh_Hans : jeton d'accès
pt_BR : Token de Acesso
ja_jp : Le stoker acoustique
zh_Hant : Accès au sceptre
placeholder.
fr_US : Veuillez saisir votre clé d'accès Dropbox
zh_Hans : Veuillez saisir votre jeton d'accès Dropbox !
pt_BR : Veuillez saisir votre jeton d'accès à Dropbox.
ja_jp : Dropbox アクセストークンを入力してください
zh_Hant : Veuillez saisir votre clé d'accès à Dropbox.
aider.
fr_US : Obtenez votre clé d'accès à partir de la Dropbox App Console
zh_Hans : Obtenir un jeton d'accès depuis la console de l'application Dropbox
pt_BR : Obtenir un jeton d'accès dans la console d'applications Dropbox
ja_JP : Dropbox アプリコンソールからアクセストークンを取得してください
zh_Hant : Veuillez obtenir votre clé d'accès à partir de la console de l'application Dropbox.
url.
des outils.
- tools/list_files.yaml
- tools/search_files.yaml
- tools/upload_file.yaml
- tools/download_file.yaml
- tools/create_folder.yaml
- tools/delete_file.yaml
supplémentaires.
python.
source : provider/dropbox.py
Points clés à retenir
Section Identité : Bien qu'elle n'affecte pas la place de marché, elle est toujours nécessaire dans la structure du fichier. Inclure des informations de base comme le nom, l'auteur et la description. Les balises doivent hériter du fichier manifest.yaml.
Section des pouvoirs.
Chaque identifiant a besoin d'un identifiant unique (comme le jeton d'accès à Dropbox).
options de type.
entrée secrète : pour les informations sensibles qui seront cryptées
text-input : Pour les informations textuelles régulières
select : pour la sélection déroulante
booléen : pour les interrupteurs à bascule
tool-selector : pour les objets de configuration d'outils
Inclure obligatoire : vrai/faux pour indiquer si le titre est obligatoire
Fournir des étiquettes, des espaces réservés et des textes d'aide conviviaux dans différentes langues.
Le champ url renvoie à la documentation permettant d'obtenir des informations d'identification.
Section des outils.
Liste les fichiers YAML pour chaque outil de votre plugin
Les chemins doivent être relatifs à la racine du plugin.
Section supplémentaire.
Spécifie le fichier Python qui valide les informations d'identification.
Ce fichier doit correspondre à celui créé dans votre "provider/your_plugin.py".
Création du fichier YAML
Pour l'adapter à votre propre service.
Modifiez la section identité avec les informations de base de votre plugin
Définissez les informations d'identification dont votre service a besoin dans la section credentials_for_provider.
Lister les fichiers YAML de vos outils dans la section outils
Spécifiez votre fichier de validation Python dans la section supplémentaire
N'oubliez pas que ce fichier YAML fonctionne en conjonction avec votre fichier de validation Python, qui utilisera ces informations d'identification pour s'authentifier auprès de votre service.
3. comment éditer provider/your_plugin.py
Vous êtes chargé de créer le fichier d'authentification du fournisseur pour un plugin Dify. Ce fichier validera les informations d'identification nécessaires pour accéder à une API tierce. Je vais vous guider dans la création de ce fichier, en utilisant l'intégration de l'API Google Search comme exemple.
Objet du dossier
Le fichier Python provider (provider_name.py) sert de module de test d'authentification pour votre plugin Dify. Sa principale responsabilité est de tester si les informations d'identification fournies par les utilisateurs sont valides en effectuant un simple appel API au service.
Composants requis
Votre classe de fournisseur doit hériter de dify_plugin.
Vous devez implémenter la méthode _validate_credentials
Vous devez utiliser ToolProviderCredentialValidationError pour gérer les erreurs.
Comment ça marche
Le processus d'authentification se déroule comme suit.
L'utilisateur saisit ses données d'identification dans l'interface utilisateur de Dify.
Dify transmet ces informations d'identification à votre méthode _validate_credentials
Votre code tente un simple appel à l'API en utilisant les informations d'identification fournies.
Si l'authentification est réussie, elle est valide ; si elle ne l'est pas, un message d'erreur s'affiche.
Exemple de mise en œuvre
Voici comment mettre en place un fichier fournisseur pour l'outil Dropbox
from typing import Any

from dify_plugin import ToolProvider
from dify_plugin.errors.tool.import ToolProviderCredentialValidationError
importer dropbox
from dropbox.exceptions import AuthError

from dropbox_utils import DropboxUtils

classe DropboxProvider(ToolProvider).
def _validate_credentials(self, credentials : dict[str, Any]) -> None.
essayer.
# Vérifier si le code d'accès (access_token) est fourni dans les informations d'identification (credentials)
if "access_token" not in credentials or not credentials.get("access_token") :.
raise ToolProviderCredentialValidationError("Le jeton d'accès Dropbox est requis.")

# Essayer de s'authentifier auprès de Dropbox en utilisant le jeton d'accès
essayer.
# Utiliser la fonction d'utilité pour obtenir un client
DropboxUtils.get_client(credentials.get("access_token"))
except AuthError as e.
raise ToolProviderCredentialValidationError(f "Jeton d'accès Dropbox invalide : {str(e)}")
sauf Exception comme e.
raise ToolProviderCredentialValidationError(f "Échec de la connexion à Dropbox : {str(e)}")

sauf Exception comme e.
raise ToolProviderCredentialValidationError(str(e))
Points clés à retenir
Toujours utiliser la classe d'outils : le fournisseur n'effectue pas d'appels d'API directement, mais utilise la classe d'outils par l'intermédiaire de la méthode from_credentials.
Utilisez une requête de test minimale : votre test de validation doit être simple - juste assez pour confirmer que les informations d'identification fonctionnent.
Gestion correcte des erreurs : intégrez toujours votre validation dans un bloc try/except et convertissez toutes les exceptions en erreurs standard de type ToolProviderCredentialValidationError.
Dictionnaire générique des informations d'identification : le paramètre des informations d'identification contient tous les paramètres d'authentification définis dans le fichier provider_name.yaml.
Gestion des générateurs : notez la syntaxe for _ in ... utilisée pour gérer le générateur renvoyé par la méthode invoke.
4. comment éditer tools/your_plugin.yaml
Vous êtes chargé de créer le fichier YAML de configuration de l'outil pour un plugin Dify. Ce fichier définit comment votre outil apparaît dans l'interface Dify, quels paramètres il accepte et comment ces paramètres sont présentés à la fois aux utilisateurs et à l'agent d'IA. paramètres qu'il accepte, et comment ces paramètres sont présentés aux utilisateurs et à l'agent IA. Je vais vous guider dans la création de ce fichier, en utilisant Google Search comme exemple. Search comme exemple.
Schéma Yaml de tools/votre_plugin.yaml.
import base64
import contextlib
import uuid
from collections.abc import Mapping
from enum import Enum, StrEnum
from typing import Any, Optional, Union

de pydantic import (
Modèle de base.
Domaine.
field_serializer.
field_validator.
modèle_validateur,
)

from dify_plugin.core.utils.yaml_loader import load_yaml_file
from dify_plugin.entities import I18nObject
from dify_plugin.entities.model.message.import PromptMessageTool

classe LogMetadata(str, Enum).
STARTED_AT = "started_at" (date de début)
FINISHED_AT = "finished_at" (date de fin)
ELAPSED_TIME = "elapsed_time" (temps écoulé)
TOTAL_PRICE = "total_price"
TOTAL_TOKENS = "total_tokens"
fournisseur = "fournisseur"
CURRENCY = "devise"

classe CommonParameterType(Enum).
SECRET_INPUT = "secret-input" (entrée secrète)
TEXT_INPUT = "entrée texte"
SELECT = "select"
STRING = "string"
NUMBER = "nombre"
FILE = "fichier"
FILES = "fichiers"
BOOLEAN = "booléen"
APP_SELECTOR = "app-selector" (sélecteur d'applications)
MODEL_SELECTOR = "sélecteur de modèle"
# TOOL_SELECTOR = "sélecteur d'outils"
TOOLS_SELECTOR = "array[tools]"

classe AppSelectorScope(Enum).
ALL = "tous"
CHAT = "chat"
FLUX DE TRAVAIL = "workflow" (flux de travail)
COMPLETION = "achèvement"

classe ModelConfigScope(Enum).
LLM = "llm"
TEXT_EMBEDDING = "insertion de texte"
RERANK = "rerank"
TTS = "tts"
SPEECH2TEXT = "speech2text" (texte du discours)
MODERATION = "modération"
VISION = "vision"

classe ToolSelectorScope(Enum).
ALL = "tous"
PLUGIN = "plugin"
API = "api"
WORKFLOW = "flux de travail"

classe ToolRuntime(BaseModel).
credentials : dict[str, Any]user_id : Optional[str]session_id : Optional[str]

classe ToolInvokeMessage(BaseModel).
classe TextMessage(BaseModel).
texte : str

def to_dict(self).
return {"text" : self.text}

classe JsonMessage(BaseModel).
json_object : dict

def to_dict(self).
return {"json_object" : self.json_object}

classe BlobMessage(BaseModel).
blob : octets

classe BlobChunkMessage(BaseModel).
id : str = Field(... , description="L'identifiant du blob")
sequence : int = Field(... , description="La séquence du morceau")
total_length : int = Field(... , description="Longueur totale du blob")
blob : bytes = Field(... , description="Les données blob du morceau")
end : bool = Field(... , description="Si le morceau est le dernier morceau")

classe VariableMessage(BaseModel).
nom_variable : str = Field(
...,
description="Le nom de la variable, ne prend en charge que les variables de niveau racine".
)
variable_value : Any = Field(... , description="La valeur de la variable")
stream : bool = Field(default=False, description="Si la variable est streamée")

@model_validator(mode="before")
@classmethod
def validate_variable_value_and_stream(cls, values).
# sauter la validation si values n'est pas un dict
if not isinstance(values, dict): : if not isinstance(values, dict) : if not isinstance(values, dict).
valeurs de retour

si values.get("stream") et non isinstance(values.get("variable_value"), str).
raise ValueError("Lorsque 'stream' est True, 'variable_value' doit être une chaîne de caractères")
valeurs de retour

classe LogMessage(BaseModel).
classe LogStatus(Enum).
START = "début"
ERROR = "erreur"
SUCCESS = "succès"

id : str = Field(default_factory=lambda : str(uuid.uuid4()), description="L'identifiant du journal")
label : str = Field(... , description="L'étiquette du journal")
parent_id : Optional[str] = Field(default=None, description="Leave empty for root log")
error : Optional[str] = Field(default=None, description="Le message d'erreur")
status : LogStatus = Champ(... , description="L'état du journal")
data : Mapping[str, Any] = Field(... , description="Données détaillées du journal")
metadata : Optional[Mapping[LogMetadata, Any]] = Field(default=None, description="Les métadonnées du journal")

classe MessageType(Enum).
TEXT = "texte"
FILE = "fichier"
BLOB = "blob"
JSON = "json"
LINK = "lien"
IMAGE = "image"
IMAGE_LINK = "image_link" (lien vers l'image)
VARIABLE = "variable"
BLOB_CHUNK = "blob_chunk"
LOG = "log"

type : MessageType
# TODO : pydantic validera et construira le message un par un, jusqu'à ce qu'il rencontre un type correct.
# nous devons optimiser le processus de construction
message : TextMessage | JsonMessage | VariableMessage | BlobMessage | BlobChunkMessage | LogMessage | None
meta : Optional[dict] = None

@field_validator("message", mode="before")
@classmethod
def decode_blob_message(cls, v).
if isinstance(v, dict) and "blob" in v.
avec contextlib.suppress(Exception).
v["blob"] = base64.b64decode(v["blob"])
retour v

@field_serializer("message")
def serialize_message(self, v).
if isinstance(v, self.BlobMessage): :
return {"blob" : base64.b64encode(v.blob).decode("utf-8")}
elif isinstance(v, self.BlobChunkMessage): :
return {
"id" : v.id,
"séquence" : v.séquence,
"longueur_totale" : v.longueur_totale,
"blob" : base64.b64encode(v.blob).decode("utf-8"),
"end" : v.end,
}
retour v

classe ToolIdentity(BaseModel).
auteur : str = Field(... , description="L'auteur de l'outil")
name : str = Field(... , description="Le nom de l'outil")
label : I18nObject = Field(... , description="L'étiquette de l'outil")

classe ToolParameterOption(BaseModel).
value : str = Field(... , description="La valeur de l'option")
label : I18nObject = Field(... , description="Le libellé de l'option")

@field_validator("value", mode="before")
@classmethod
def transform_id_to_str(cls, value) -> str.
if not isinstance(value, str) : if not isinstance(value, str).
return str(value)
d'autre part.
valeur de retour

classe ParameterAutoGenerate(BaseModel).
classe Type(StrEnum).
PROMPT_INSTRUCTION = "prompt_instruction"

type : Type

classe ParameterTemplate(BaseModel).
enabled : bool = Champ(... , description="Si le paramètre est activé par jinja")

classe ToolParameter(BaseModel).
classe ToolParameterType(str, Enum).
STRING = CommonParameterType.STRING.value
NUMBER = CommonParameterType.NUMBER.value
BOOLEAN = CommonParameterType.BOOLEAN.value
SELECT = CommonParameterType.SELECT.value
SECRET_INPUT = CommonParameterType.SECRET_INPUT.value
FILE = CommonParameterType.FILE.value
FILES = CommonParameterType.FILES.value
MODEL_SELECTOR = CommonParameterType.MODEL_SELECTOR.value
APP_SELECTOR = CommonParameterType.APP_SELECTOR.value
# TOOL_SELECTOR = CommonParameterType.TOOL_SELECTOR.value

classe ToolParameterForm(Enum).
SCHEMA = "schema" # doit être défini lors de l'ajout de l'outil
FORM = "form" # doit être défini avant d'invoquer l'outil.
LLM = "llm" # sera réglé par LLM

name : str = Field(... , description="Le nom du paramètre")
label : I18nObject = Field(... , description="L'étiquette présentée à l'utilisateur")
human_description : I18nObject = Field(... , description="La description présentée à l'utilisateur")
type : ToolParameterType = Field(... , description="Le type du paramètre")
auto_generate : Optional[ParameterAutoGenerate] = Field(
default=None, description="La génération automatique du paramètre"
)
template : Optional[ParameterTemplate] = Field(default=None, description="Le modèle du paramètre")
scope : str | None = None
form : ToolParameterForm = Field(... , description="La forme du paramètre, schema/form/llm")
llm_description : Facultatif[str] = Aucun
requis : Facultatif[bool] = False
default : Optional[Union[int, float, str]] = None
min : Facultatif [Union [float, int]] = Aucun
max : Optional[Union[float, int]] = None
précision : Facultatif[int] = Aucun
options : Optional[list[ToolParameterOption]] = None

classe ToolDescription(BaseModel).
human : I18nObject = Field(... , description="La description présentée à l'utilisateur")
llm : str = Field(... , description="La description présentée au LLM")

classe ToolConfigurationExtra(BaseModel).
classe Python(BaseModel).
source : str

python : Python

classe ToolConfiguration(BaseModel).
identité : ToolIdentity
parameters : list[ToolParameter] = Field(default=[], description="Les paramètres de l'outil")
description : ToolDescription
extra : ToolConfigurationExtra
has_runtime_parameters : bool = Champ(default=False, description="Si l'outil a des paramètres d'exécution")
output_schema : Optional[Mapping[str, Any]] = None

classe ToolLabelEnum(Enum).
SEARCH = "recherche"
IMAGE = "image"
VIDEOS = "vidéos"
WEATHER = "météo"
FINANCE = "finance"
DESIGN = "design"
TRAVEL = "voyage"
SOCIAL = "social"
NEWS = "nouvelles"
MEDICAL = "médical"
PRODUCTIVITÉ = "productivité"
EDUCATION = "éducation"
BUSINESS = "entreprise"
DIVERTISSEMENT = "divertissement"
UTILITIES = "utilités"
OTHER = "autre"

classe ToolCredentialsOption(BaseModel).
value : str = Field(... , description="La valeur de l'option")
label : I18nObject = Field(... , description="Le libellé de l'option")

classe ProviderConfig(BaseModel).
classe Config(Enum).
SECRET_INPUT = CommonParameterType.SECRET_INPUT.value
TEXT_INPUT = CommonParameterType.TEXT_INPUT.value
SELECT = CommonParameterType.SELECT.value
BOOLEAN = CommonParameterType.BOOLEAN.value
MODEL_SELECTOR = CommonParameterType.MODEL_SELECTOR.value
APP_SELECTOR = CommonParameterType.APP_SELECTOR.value
# TOOL_SELECTOR = CommonParameterType.TOOL_SELECTOR.value
TOOLS_SELECTOR = CommonParameterType.TOOLS_SELECTOR.value

@classmethod
def value_of(cls, value : str) -> "ProviderConfig.
"""
Obtenir la valeur d'un mode donné.

:param value : mode value
:return : mode
"""
pour le mode en cls.
si mode.value == value.
mode de retour
raise ValueError(f "valeur du mode invalide {valeur}")

name : str = Field(... , description="Le nom des informations d'identification")
type : Config = Field(... , description="Le type d'informations d'identification")
scope : str | None = None
requis : bool = False
default : Optional[Union[int, float, str]] = None
options : Optional[list[ToolCredentialsOption]] = None
label : I18nObject
help : Optional[I18nObject] = None
url : Optional[str] = None
placeholder : Optional[I18nObject] = None

classe ToolProviderIdentity(BaseModel).
auteur : str = Field(... , description="L'auteur de l'outil")
name : str = Field(... , description="Le nom de l'outil")
description : I18nObject = Field(... , description="La description de l'outil")
icon : str = Field(... , description="L'icône de l'outil")
label : I18nObject = Field(... , description="L'étiquette de l'outil")
tags : list[ToolLabelEnum] = Field(
default=[],
description="Les tags de l'outil".
)

classe ToolProviderConfigurationExtra(BaseModel).
classe Python(BaseModel).
source : str

python : Python

classe ToolProviderConfiguration(BaseModel).
identity : ToolProviderIdentity
credentials_schema : list[ProviderConfig] = Field(
default_factory=list,
alias="credentials_for_provider",
description="Le schéma des informations d'identification du fournisseur de l'outil".
)
tools : list[ToolConfiguration] = Field(default=[], description="Les outils du fournisseur d'outils")
extra : ToolProviderConfigurationExtra

@model_validator(mode="before")
@classmethod
def validate_credentials_schema(cls, data : dict) -> dict.
original_credentials_for_provider : dict[str, dict] = data.get("credentials_for_provider", {})

credentials_for_provider : list[dict[str, Any]] = []for name, credential in original_credentials_for_provider.items() :
credential["name"] = name
credentials_for_provider.append(credential)

data["credentials_for_provider"] = credentials_for_provider
renvoyer les données

@field_validator("tools", mode="before")
@classmethod
def validate_tools(cls, value) -> list[ToolConfiguration].
if not isinstance(value, list): : if not isinstance(value, list) : if not isinstance(value, list).
raise ValueError("les outils devraient être une liste")

outils : liste[ToolConfiguration] = []

pour l'outil en valeur :
# read from yaml
if not isinstance(tool, str) : if not isinstance(tool, str).
raise ValueError("Le chemin d'accès à l'outil doit être une chaîne de caractères")
essayer.
file = load_yaml_file(tool)
outils.append(
ToolConfiguration(
identity=ToolIdentity(**file["identity"]),
parameters=[ToolParameter(**param) for param in file.get("parameter", []) or []],
description=ToolDescription(**file["description"]),
extra=ToolConfigurationExtra(**file.get("extra", {})),
output_schema=file.get("output_schema", None),
)
)
sauf Exception comme e.
raise ValueError(f "Erreur de chargement de la configuration de l'outil : {str(e)}") from e

outils de retour

classe ToolProviderType(Enum).
"""
Classe d'énumération pour le fournisseur d'outils
"""

BUILT_IN = "construit"
WORKFLOW = "flux de travail"
API = "api"
APP = "app"
DATASET_RETRIEVAL = "dataset-retrieval" (récupération de données)

@classmethod
def value_of(cls, value : str) -> "ToolProviderType".
"""
Obtenir la valeur d'un mode donné.

:param value : mode value
:return : mode
"""
pour le mode en cls.
si mode.value == value.
mode de retour
raise ValueError(f "valeur du mode invalide {valeur}")

classe ToolSelector(BaseModel).
classe Parameter(BaseModel).
name : str = Field(... , description="Le nom du paramètre")
type : ToolParameter.ToolParameterType = Field(... , description="Le type du paramètre")
required : bool = Champ(... , description="Si le paramètre est obligatoire")
description : str = Field(... , description="La description du paramètre")
default : Optional[Union[int, float, str]] = None
options : Optional[list[ToolParameterOption]] = None

provider_id : str = Field(... , description="L'identifiant du fournisseur")
nom_outil : str = Champ(... , description="Le nom de l'outil")
tool_description : str = Field(... , description="La description de l'outil")
tool_configuration : Mapping[str, Any] = Field(... , description="Configuration, type de formulaire")
tool_parameters : Mapping[str, Parameter] = Field(... , description="Paramètres, type llm")

def to_prompt_message(self) -> PromptMessageTool.
"""
Convertir le sélecteur d'outils en outil de message d'invite, basé sur openai appel de fonction schéma.
"""
tool = PromptMessageTool(
name=self.tool_name,
description=self.tool_description,
parameters={
"type" : "objet",
"propriétés" : {},
"requis" : [],
},
)

for name, parameter in self.tool_parameters.items(): :
tool.parameters[name] = {
"type" : paramètre.type.valeur,
"description" : parameter.description,
}

si paramètre.requis.
tool.parameters["required"].append(name)

si parameter.options.
tool.parameters[name]["enum"] = [option.value for option in parameter.options]

outil de retour
Objet du dossier
Le fichier YAML de l'outil (your_plugin.yaml) définit.
Informations de base sur l'identité de votre outil
Descriptions pour les humains et l'agent IA
Paramètres acceptés par votre outil
Comment ces paramètres sont présentés et collectés
Exemple de mise en œuvre
Voici à quoi ressemblent les fichiers YAML de l'outil pour Dropbox.
ceate_folder.yaml.
l'identité.
nom : create_folder
auteur : lcandy
étiquette.
fr_US : Créer un dossier
zh_Hans : Création de dossiers
pt_BR : Criar Pasta
ja_jp : Plié
zh_Hant : Créer un dossier
description.
humaine.
fr_US : Créer un nouveau dossier dans Dropbox
zh_Hans : Création de nouveaux dossiers dans Dropbox
pt_BR : Créer de nouvelles données sur Dropbox
ja_jp : Dropbox lance une nouvelle version de Frida !
zh_Hant : Création d'un nouveau dossier dans Dropbox
llm : Crée un nouveau dossier au chemin spécifié dans Dropbox et renvoie des informations sur le dossier créé, notamment le chemin et l'ID.
paramètres.
- nom : chemin_du_dossier
type : string
obligatoire : true
étiquette.
fr_US : Chemin d'accès au dossier
zh_Hans : Chemin d'accès au dossier
pt_BR : Caminho da Pasta
ja_jp:ォルダパス
zh_Hant : chemin d'accès au dossier
description_humaine.
fr_US : Le chemin où le dossier sera créé dans Dropbox
zh_Hans : chemin de création de dossier dans Dropbox
pt_BR : Le chemin des pâtes est créé sur Dropbox
ja_jp : Dropbox でフォルダを作成するパス
zh_Hant : le chemin d'accès au dossier que vous souhaitez créer dans Dropbox.
llm_description : Le chemin où le dossier sera créé dans Dropbox. Il doit être spécifié comme un chemin complet, comme '/Documents/Projets' ou '/Photos/ Vacation2023". Les chemins sont sensibles à la casse et doivent commencer par une barre oblique.
forme : llm
supplémentaires.
python.
source : tools/create_folder.py
delete_file.yaml.
l'identité.
nom : delete_file
auteur : lcandy
étiquette.
fr_US : Supprimer un fichier/dossier
zh_Hans : Supprimer des fichiers/dossiers
pt_BR : Excluir Arquivo/Pasta
ja_jp : ファイル/フォルダ削除
zh_Hant : Supprimer un fichier/dossier
description.
humaine.
fr_US : Supprimer un fichier ou un dossier de Dropbox
zh_Hans : Suppression de fichiers ou de dossiers dans Dropbox
pt_BR : Exclure un fichier ou des données de Dropbox
ja_jp : Dropbox からファイルやフォルダを削除します
zh_Hant : Supprimer un fichier ou un dossier de Dropbox
llm : Supprime définitivement un fichier ou un dossier de Dropbox au chemin spécifié. Renvoie des informations de confirmation sur l'élément supprimé.
paramètres.
- nom : chemin_fichier
type : string
obligatoire : true
étiquette.
fr_US : Chemin d'accès au fichier/dossier
zh_Hans : chemin d'accès au fichier/dossier
pt_BR : Caminho do Arquivo/Pasta
ja_jp:ファイル/フォルダパス
zh_Hant : chemin d'accès au fichier/dossier
description_humaine.
fr_US : Le chemin du fichier ou du dossier à supprimer de Dropbox
zh_Hans : Chemin d'accès au fichier ou au dossier à supprimer de Dropbox
pt_BR : Le chemin d'accès à l'archive ou à la pâte pour exclure Dropbox
ja_jp : Dropbox から削除するファイルやフォルダのパス
zh_Hant : Chemin d'accès au fichier ou au dossier que vous souhaitez supprimer de Dropbox
llm_description : Chemin d'accès au fichier ou au dossier à supprimer de Dropbox. Il doit s'agir d'un chemin complet, comme "/Documents/report.txt" ou "/Photos /Vacation2023". Les chemins d'accès sont sensibles à la casse et doivent commencer par une barre oblique. ATTENTION - Il s'agit d'une suppression permanente.
forme : llm
supplémentaires.
python.
source : tools/delete_file.py
download_file.py.
l'identité.
nom : download_file
auteur : lcandy
étiquette.
fr_US : Télécharger le fichier
zh_Hans : Télécharger le fichier
pt_BR : Baixar Arquivo
ja_jp : ファイルダウンロード
zh_Hant : Télécharger le fichier
description.
humaine.
fr_US : Télécharger un fichier depuis Dropbox
zh_Hans : Téléchargement de fichiers depuis Dropbox
pt_BR : Ajouter un fichier à Dropbox
ja_jp : Dropbox からファイルをダウンロードします
zh_Hant : Télécharger des fichiers depuis Dropbox
llm : télécharge un fichier depuis Dropbox au chemin spécifié. renvoie les métadonnées du fichier et éventuellement le contenu du fichier (en base64 pour les fichiers binaires ou en texte pour les fichiers texte). pour les fichiers texte).
paramètres.
- nom : chemin_fichier
type : string
obligatoire : true
étiquette.
fr_US : Chemin d'accès au fichier
zh_Hans : chemin d'accès au fichier
pt_BR : Caminho do Arquivo
ja_jp : ファイルパス
zh_Hant : Chemins d'accès aux fichiers
description_humaine.
fr_US : Le chemin du fichier à télécharger depuis Dropbox
zh_Hans : chemin d'accès au fichier à télécharger depuis Dropbox
pt_BR : Le chemin d'accès à l'interface pour accéder à Dropbox
ja_JP : Dropbox からダウンロードするファイルのパス
zh_Hant : le chemin d'accès au fichier que vous souhaitez télécharger depuis Dropbox
llm_description : Le chemin d'accès du fichier à télécharger depuis Dropbox. Il doit inclure le chemin d'accès complet avec le nom de fichier et l'extension, comme '/Documents/report. txt". Les chemins sont sensibles à la casse et doivent commencer par une barre oblique.
forme : llm
- nom : include_content
type : booléen
obligatoire : false
par défaut : false
étiquette.
fr_US : Inclure le contenu
zh_Hans : Contenu
pt_BR : Inclure des informations
ja_JP : Contenu
zh_Hant : Contient du contenu
description_humaine.
en_US : Inclure ou non le contenu du fichier dans la réponse
zh_Hans : inclure ou non le contenu du fichier dans la réponse
pt_BR : Inclure le contenu de l'article dans la réponse
ja_jp : Le contenu du film dans les Rathponies est inclus dans le film.
zh_Hant : inclure ou non le contenu du fichier dans la réponse
llm_description : La valeur true permet d'inclure le contenu du fichier dans la réponse. Pour les petits fichiers texte, le contenu sera fourni sous forme de texte. Pour les fichiers binaires, le contenu sera fourni sous forme de chaîne encodée en base64. La valeur par défaut est false.
forme : llm
supplémentaires.
python.
source : tools/download_file.py

dropbox.yaml.
l'identité.
nom : dropbox
auteur : lcandy
étiquette.
fr_US : Dropbox
zh_Hans : Dropbox
pt_BR : Dropbox
ja_JP : Dropbox
zh_Hant : Dropbox
description.
humaine.
fr_US : Interagir avec Dropbox
zh_Hans : Interagir avec Dropbox
pt_BR : Interagir avec Dropbox
ja_JP : Dropbox et connectivité
zh_Hant : Interagir avec Dropbox
llm : permet d'accéder aux services Dropbox et d'interagir avec les fichiers et les dossiers d'un compte Dropbox.
paramètres.
- nom : query
type : string
obligatoire : true
étiquette.
fr_US : Chaîne de requête
zh_Hans : Déclaration de requête
pt_BR : Termo de consulta
ja_jp : Colonnes de texte K'eri
zh_Hant : Déclaration de demande de renseignements
description_humaine.
fr_US : Entrez votre requête d'opération Dropbox
zh_Hans : Entrez votre requête d'opération Dropbox
pt_BR : Numérisez votre consultation d'exploitation de Dropbox
ja_JP : Opération Dropbox クエリを入力してください
zh_Hant : veuillez saisir l'opération Dropbox que vous souhaitez effectuer.
llm_description : requête décrivant l'opération Dropbox à effectuer.
forme : llm
supplémentaires.
python.
source : tools/dropbox.py
Composants clés
Section Identité.
name : Nom interne de votre outil (doit correspondre au nom de vos fichiers)
auteur : qui a créé l'outil
label : Affichage du nom dans différentes langues
Description Section.
humain : description présentée à des utilisateurs humains dans différentes langues
llm : description fournie à l'agent IA pour qu'il comprenne ce que fait votre outil et comment l'utiliser
Section des paramètres.
Liste des paramètres acceptés par votre outil, chacun avec.
name : Identifiant du paramètre (utilisé dans votre code Python)
type : Type de données (chaîne, nombre, booléen, etc.)
obligatoire : si ce paramètre est obligatoire
étiquette : nom convivial dans différentes langues
human_description : Explication pour les utilisateurs humains dans différentes langues
llm_description : Explication permettant à l'agent IA de comprendre ce paramètre
formulaire : comment le paramètre est collecté
llm : un agent d'intelligence artificielle extrait des requêtes de l'utilisateur
flux de travail : l'utilisateur doit fournir une variable dans l'interface utilisateur
Facultatif : default : valeur par défaut de ce paramètre
Section supplémentaire.
python.source : Chemin d'accès au fichier d'implémentation Python de votre outil
Notes importantes
Séparation des fichiers.
Important !!!! Si votre outil a différentes fonctionnalités, comme lire et écrire un email, ou lire ou mettre à jour une base de données, vous devez séparer le fichier yaml en plusieurs fichiers. Le principe est que chaque fichier yaml et chaque fichier de code sont exclusivement destinés à l'exécution de chaque type d'outil. Le fichier lui-même ne doit extraire que les paramètres que l'outil doit extraire. Par exemple, pour lire et mettre à jour une base de données, vous devez utiliser deux fichiers yaml : read_database.yaml et update_ database.yaml séparément. Le fichier yaml read_database.yaml doit être lu et mis à jour séparément.
Descriptions du LLM.
La description de l'outil et des paramètres est cruciale : elle indique à l'agent d'intelligence artificielle comment utiliser l'outil.
Soyez clair sur les paramètres nécessaires et sur les informations que votre outil vous renverra.
Cela aide l'agent d'IA à décider quand utiliser votre outil et comment extraire les paramètres des requêtes des utilisateurs
Configuration des paramètres.
Pour chaque paramètre, précisez s'il est obligatoire
Choisir le type de données approprié
Définissez le formulaire à llm si vous souhaitez que l'IA l'extraie des requêtes de l'utilisateur.
Réglez le formulaire sur le flux de travail si vous voulez que les utilisateurs le fournissent directement.
Localisation.
Fournir des traductions pour les étiquettes et les descriptions dans plusieurs langues, le cas échéant.
Au minimum, inclure l'anglais (en_US)
Pour créer votre propre fichier YAML, adaptez cette structure à votre outil spécifique, en définissant clairement les paramètres dont il a besoin et la manière dont ils doivent être présentés à la fois aux humains et à l'agent d'IA. à l'homme et à l'agent d'intelligence artificielle.
5. comment éditer tools/your_plugin.py
Vous êtes chargé de créer le fichier d'implémentation de l'outil pour un plugin Dify. Ce fichier contient la logique réelle de votre outil qui effectue des requêtes API et traite les résultats. Ce fichier contient la logique réelle de votre outil qui effectue des requêtes API et traite les résultats. Je vais vous guider dans la création de ce fichier, en utilisant Google Search comme exemple.
Objet du dossier
Le fichier Python de l'outil (your_plugin.py) est responsable de.
Faire des demandes d'API à votre service
Traitement des réponses
Renvoyer les résultats dans un format utilisable par Dify
Composants requis
Votre classe d'outils doit hériter de dify_plugin.
Vous devez implémenter la méthode _invoke qui renvoie un générateur
Vous devez inclure ces importations essentielles.
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.tool.import ToolInvokeMessage
Exemple de mise en œuvre
Voici à quoi ressemble l'implémentation de l'outil Dropbox.
ceate_folder.yaml.
from collections.abc import Generator
from typing import Any

from dify_plugin import Tool
from dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError

from dropbox_utils import DropboxUtils

classe CreateFolderTool(Tool).
def _invoke(self, tool_parameters : dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Créer un dossier dans Dropbox
"""
# Paramètres d'acquisition
chemin_du_dossier = tool_parameters.get("chemin_du_dossier", "")

# Valider les paramètres
si pas chemin_du_dossier : si pas chemin_du_dossier : si pas chemin_du_dossier.
yield self.create_text_message("Le chemin d'accès au dossier Dropbox est requis.")
retour

# Assurez-vous que le chemin d'accès au dossier commence par /
if not folder_path.startswith("/") :.
chemin_du_dossier = "/" + chemin_du_dossier

essayer.
# Obtenir un jeton d'accès à partir des informations d'identification
access_token = self.runtime.credentials.get("access_token")
if not access_token.
yield self.create_text_message("Le jeton d'accès Dropbox est requis.")
retour

# Obtenir un client Dropbox
essayer.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "L'authentification a échoué : {str(e)}")
retour
sauf Exception comme e.
yield self.create_text_message(f "Échec de la connexion à Dropbox : {str(e)}")
retour

# Créer le dossier
essayer.
result = DropboxUtils.create_folder(dbx, folder_path)

# Créer une réponse
summary = f "Folder '{result['name']}' created successfully at '{result['path']}'"
yield self.create_text_message(summary)
yield self.create_json_message(result)

except ApiError as e.
if "path/conflict" in str(e).
yield self.create_text_message(f "Un dossier existe déjà à '{chemin_du_dossier}'")
d'autre part.
yield self.create_text_message(f "Erreur lors de la création du dossier : {str(e)}")
retour

sauf Exception comme e.
yield self.create_text_message(f "Erreur : {str(e)}")
retour
delete_file.py
from collections.abc import Generator
from typing import Any

from dify_plugin import Tool
from dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError

from dropbox_utils import DropboxUtils

classe DeleteFileTool(Tool).
def _invoke(self, tool_parameters : dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Supprimer un fichier ou un dossier de Dropbox
"""
# Paramètres d'acquisition
file_path = tool_parameters.get("file_path", "")

# Valider les paramètres
si pas de chemin d'accès au fichier : si pas de chemin d'accès au fichier : si pas de chemin d'accès au fichier.
yield self.create_text_message("Le chemin du fichier ou du dossier dans Dropbox est requis.")
retour

# Assurez-vous que le chemin d'accès commence par /
if not file_path.startswith("/") :.
chemin_fichier = "/" + chemin_fichier

essayer.
# Obtenir un jeton d'accès à partir des informations d'identification
access_token = self.runtime.credentials.get("access_token")
if not access_token.
yield self.create_text_message("Le jeton d'accès Dropbox est requis.")
retour

# Obtenir un client Dropbox
essayer.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "L'authentification a échoué : {str(e)}")
retour
sauf Exception comme e.
yield self.create_text_message(f "Échec de la connexion à Dropbox : {str(e)}")
retour

# Supprimer le fichier ou le dossier
essayer.
result = DropboxUtils.delete_file(dbx, file_path)

# Créer une réponse
summary = f"'{result['name']}' supprimé avec succès"
yield self.create_text_message(summary)
yield self.create_json_message(result)

except ApiError as e.
if "path/not_found" in str(e): :
yield self.create_text_message(f "Fichier ou dossier introuvable à '{chemin_du_fichier}'")
d'autre part.
yield self.create_text_message(f "Erreur de suppression du fichier/dossier : {str(e)}")
retour

sauf Exception comme e.
yield self.create_text_message(f "Erreur : {str(e)}")
retour
download_file.yaml.
from collections.abc import Generator
import base64
from typing import Any

from dify_plugin import Tool
from dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError

from dropbox_utils import DropboxUtils

classe DownloadFileTool(Tool).
def _invoke(self, tool_parameters : dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Télécharger un fichier depuis Dropbox
"""
# Paramètres d'acquisition
file_path = tool_parameters.get("file_path", "")
include_content = tool_parameters.get("include_content", False)

# Valider les paramètres
si pas de chemin d'accès au fichier : si pas de chemin d'accès au fichier : si pas de chemin d'accès au fichier.
yield self.create_text_message("Le chemin d'accès au fichier Dropbox est requis.")
retour

# Assurez-vous que le chemin d'accès au fichier commence par /
if not file_path.startswith("/") :.
chemin_fichier = "/" + chemin_fichier

essayer.
# Obtenir un jeton d'accès à partir des informations d'identification
access_token = self.runtime.credentials.get("access_token")
if not access_token.
yield self.create_text_message("Le jeton d'accès Dropbox est requis.")
retour

# Obtenir un client Dropbox
essayer.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "L'authentification a échoué : {str(e)}")
retour
sauf Exception comme e.
yield self.create_text_message(f "Échec de la connexion à Dropbox : {str(e)}")
retour

# Télécharger le fichier
essayer.
result = DropboxUtils.download_file(dbx, file_path)

# Créer une réponse
réponse = {
"nom" : résultat["nom"],
"path" : résultat["path"],
"id" : result["id"],
"taille" : résultat["taille"],
"modified" : result["modified"]}

# Inclure le contenu si demandé
si include_content.
# Encoder le contenu binaire en base64
response["content_base64"] = base64.b64encode(result["content"]).decode('utf-8')

# Essayer de décoder le texte s'il est suffisamment petit
if result["size"] < 1024 * 1024 : # Moins de 1MB
essayer.
text_content = result["content"].decode('utf-8')
response["content_text"] = text_content
except UnicodeDecodeError.
# Pas un fichier texte, il suffit d'inclure base64
passer

summary = f "Le fichier '{résultat['nom']}' a été téléchargé avec succès"
yield self.create_text_message(summary)
yield self.create_json_message(response)

except ApiError as e.
yield self.create_text_message(f "Erreur de téléchargement du fichier : {str(e)}")
retour

sauf Exception comme e.
yield self.create_text_message(f "Erreur : {str(e)}")
retour
Points clés à retenir
Séparation des fichiers.
Important : Si votre outil a différentes fonctionnalités, comme lire et écrire un email, ou lire ou mettre à jour une base de données, vous devez séparer le fichier yaml en plusieurs fichiers. Le principe est que chaque fichier yaml et code est exclusivement destiné à l'exécution de chaque type d'outil. Le fichier lui-même ne doit extraire que les paramètres que la fonctionnalité de l'outil utilisera. Par exemple, pour lire et mettre à jour une base de données, vous devez utiliser deux fichiers yaml : read_database.py et update_ database.py séparément. Le fichier yaml read_database.py doit être utilisé séparément pour lire la base de données et la mettre à jour.
Importations requises : incluez toujours les importations essentielles en tête de votre fichier.
Héritage de classe : votre classe d'outil doit hériter de dify_plugin.
Extraction des paramètres.
Le dictionnaire tool_parameters contient tous les paramètres définis dans le fichier YAML de votre outil.
Accéder directement à ces paramètres à l'aide de clés de dictionnaire, par exemple tool_parameters["query"] Ces paramètres sont automatiquement extraits des requêtes de l'utilisateur par l'agent d'intelligence artificielle. Ces paramètres sont automatiquement extraits des requêtes de l'utilisateur par l'agent d'intelligence artificielle.
Veillez à traiter tous les paramètres requis et à fournir un traitement d'erreur approprié s'ils sont manquants.
Exemple.
query = tool_parameters["query"] # Extraction du paramètre de la requêtelimit = tool_parameters.get("limit", 10) # Extraction avec une valeur par défaut# Validation facultativesi not query : raise ValueError("Query parameter cannot be empty")
Accès aux données d'identification.
Accédez à vos informations d'authentification en utilisant self.runtime.credentials
Les clés correspondent à celles définies dans le fichier YAML de votre fournisseur.
Exemple : self.runtime.credentials["serpapi_api_key"] Traitement des réponses : créez une méthode d'aide pour extraire uniquement les informations pertinentes des réponses de l'API. réponses de l'API.
Renvoi des résultats : Vous devez utiliser yield avec l'une des méthodes de création de message pour renvoyer des données.
Lorsque vous mettez en œuvre votre propre outil, veillez à extraire correctement tous les paramètres dont vous avez besoin du dictionnaire tool_parameters, et à les valider si nécessaire. Les paramètres disponibles sont définis dans le fichier YAML de votre outil et seront automatiquement extraits des requêtes des utilisateurs par l'agent IA.
6. comment créer PRIVACY.md et README.md
Vous êtes chargé de créer la politique de confidentialité et les fichiers readme pour votre plugin Dify. Ces fichiers sont écrits au format Markdown et servent des objectifs importants pour les utilisateurs et les développeurs de votre plugin. Ces fichiers sont écrits au format Markdown et sont importants pour les utilisateurs et les développeurs de votre plugin.
PRIVACY.md
Le fichier PRIVACY.md les grandes lignes les pratiques de votre plugin en matière de protection de la vie privée, y compris les données qu'il collecte et la manière dont elles sont utilisées. Il s'agit d'une information essentielle pour les utilisateurs soucieux de la confidentialité de leurs données. Il s'agit d'informations essentielles pour les utilisateurs soucieux de la confidentialité de leurs données.
Ce qu'il faut inclure
D'après le texte de remplacement que vous avez partagé (" !!!!! Veuillez remplir la politique de confidentialité du plugin"), vous devriez inclure.
Quelles sont les données collectées par votre plugin ?
Comment ces données sont-elles stockées et traitées ?
Quels sont les services tiers utilisés (le cas échéant) ?
Droits des utilisateurs concernant leurs données
Durée de conservation des données
Coordonnées des personnes à contacter en cas de problèmes liés à la protection de la vie privée
Exemple de structure
# Politique de confidentialité

## Collecte des données
[Décrivez les données utilisateur collectées par votre plugin et pourquoi].

## Traitement des données
[Expliquer comment les données collectées sont traitées].

## Services de tiers
[Liste des services tiers utilisés par votre plugin et lien vers leur politique de confidentialité].

## Conservation des données
[Expliquer la durée de conservation des données des utilisateurs].

## Droits de l'utilisateur
[Décrire les droits des utilisateurs concernant leurs données].

## Informations de contact
[Fournir des informations de contact pour les demandes relatives à la protection de la vie privée].

Dernière mise à jour : [Date]README.md
Le fichier README.md fournit des informations essentielles sur votre plugin, notamment ce qu'il fait, comment l'installer et comment l'utiliser. document auquel la plupart des utilisateurs et des développeurs se réfèrent.
Ce qu'il faut inclure
Sur la base de l'exemple que vous avez partagé (Jira plugin readme), vous devriez inclure.
Nom du plugin comme titre principal
Informations sur l'auteur
Informations sur la version
Type de plugin
Description détaillée de ce que fait le plugin
Instructions d'installation
Exemples d'utilisation
Options de configuration
Informations sur le dépannage
Exemple de structure
# Votre nom de plugin

**Auteur:** [Votre nom ou votre organisation]**Version:** [Numéro de version actuel]**Type:** [Type de plugin]

## Description
[Fournissez une description détaillée de ce que fait votre plugin]

## Caractéristiques
- [Caractéristique 1]- [Caractéristique 2]- [Caractéristique 3]

## Installation
[Fournir des instructions d'installation étape par étape]

## Configuration
[Expliquez comment configurer votre plugin].

## Exemples d'utilisation
[Fournir des exemples d'utilisation de votre plugin].

## Dépannage
[Énumérer les problèmes courants et leurs solutions]

## Contribuant
[Expliquez comment d'autres personnes peuvent contribuer à votre plugin].

## Licence
[Précisez la licence sous laquelle votre plugin est publié]Utilisation d'images
Comme vous l'avez mentionné, si vous souhaitez inclure des images dans l'un ou l'autre document.
Stocker les images dans le dossier _assets
Référencez-les dans votre document Markdown en utilisant des chemins d'accès relatifs.
! [Description de l'image](_assets/image_name.png)
Ces deux fichiers doivent être écrits au format Markdown (extension .md) et placés dans le répertoire racine de votre projet de plugin. Veillez à les mettre à jour au fur et à mesure de l'évolution de votre plugin. Veillez à les mettre à jour au fur et à mesure de l'évolution de votre plugin.
Exigences.txt
Vous devez toujours utiliser les dernières dépendances en utilisant ~= dans votre fichier txt, et le dify_plugin~=0.0.1b72 est indispensable.

© déclaration de droits d'auteur

Articles connexes

Pas de commentaires

Vous devez être connecté pour participer aux commentaires !
S'inscrire maintenant
aucun
Pas de commentaires...