Browse Source

feat: tool configuration

Yeuoly 1 year ago
parent
commit
6b3c004edb

+ 0 - 4
examples/baisc_math/.gitignore

@@ -1,4 +0,0 @@
-__pycache__
-install.sh
-.installed
-dify_plugin

+ 0 - 1
examples/baisc_math/launch.sh

@@ -1 +0,0 @@
-activate basic_math && python -m main

+ 0 - 26
examples/baisc_math/main.py

@@ -1,26 +0,0 @@
-from typing import Generator
-from dify_plugin import ToolProvider, Plugin
-from dify_plugin.tool.entities import ToolInvokeTextMessage, ToolProviderConfiguration
-from dify_plugin.tool.tool import Tool
-from dify_plugin.tool.entities import ToolConfiguration, ToolInvokeMessage
-
-plugin = Plugin()
-
-@plugin.register_tool_provider
-class BasicMath(ToolProvider):
-    @classmethod
-    def configuration(cls) -> ToolProviderConfiguration:
-        return ToolProviderConfiguration(name='basic_math')
-
-@plugin.register_tool(BasicMath)
-class Add(Tool):
-    @classmethod
-    def configuration(cls) -> ToolConfiguration:
-        return ToolConfiguration(name='add')
-    
-    def _invoke(self, user_id: str, tool_parameter: dict) -> Generator[ToolInvokeMessage, None, None]:
-        result = tool_parameter['a'] + tool_parameter['b']
-        yield self.create_text_message(f'The result is {result}')
-
-if __name__ == '__main__':
-    plugin.run()

+ 0 - 28
examples/baisc_math/manifest.json

@@ -1,28 +0,0 @@
-{
-    "version": "0.0.1",
-    "author": "Yeuoly",
-    "name": "basic_math",
-    "datetime": 1719812022,
-    "module": "main",
-    "resource": {
-        "memory": 1048576,
-        "storage": 1048576,
-        "permission": {
-            "tool": {
-                "enabled": true
-            },
-            "model": {
-                "enabled": true,
-                "llm": true
-            }
-        }
-    },
-    "meta": {
-        "version": "0.0.1",
-        "arch": ["amd64", "arm64"],
-        "runner" : {
-            "language": "python",
-            "version": "3.12"
-        }
-    }
-}

+ 0 - 1
examples/baisc_math/requirements.txt

@@ -1 +0,0 @@
-requests==2.28.1

+ 0 - 25
examples/baisc_math/test.py

@@ -1,25 +0,0 @@
-class SimpleApp:
-    def __init__(self):
-        self.routes = {}
-
-    def route(self, path):
-        def decorator(func):
-            self.routes[path] = func
-            return func
-        return decorator
-
-    def execute(self, path):
-        if path in self.routes:
-            return self.routes[path]()
-        else:
-            raise ValueError("Route not found!")
-
-app = SimpleApp()
-
-@app.route("/")
-def home():
-    return "Welcome to the home page!"
-
-@app.route("/about")
-def about():
-    return "About us page!"

+ 22 - 13
internal/core/dify_invocation/types.go

@@ -3,12 +3,14 @@ package dify_invocation
 import (
 	"encoding/json"
 	"fmt"
+
+	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/model_entities"
 )
 
 type BaseInvokeDifyRequest struct {
-	TenantId string `json:"tenant_id"`
-	UserId   string `json:"user_id"`
-	Type     string `json:"type"`
+	TenantId string     `json:"tenant_id"`
+	UserId   string     `json:"user_id"`
+	Type     InvokeType `json:"type"`
 }
 
 func (r *BaseInvokeDifyRequest) FromMap(data map[string]any) error {
@@ -21,24 +23,27 @@ func (r *BaseInvokeDifyRequest) FromMap(data map[string]any) error {
 		return fmt.Errorf("user_id is not a string")
 	}
 
-	if r.Type, ok = data["type"].(string); !ok {
+	if r.Type, ok = data["type"].(InvokeType); !ok {
 		return fmt.Errorf("type is not a string")
 	}
 
 	return nil
 }
 
+type InvokeType string
+
 const (
-	INVOKE_TYPE_MODEL = "model"
-	INVOKE_TYPE_TOOL  = "tool"
-	INVOKE_TYPE_NODE  = "node"
+	INVOKE_TYPE_MODEL InvokeType = "model"
+	INVOKE_TYPE_TOOL  InvokeType = "tool"
+	INVOKE_TYPE_NODE  InvokeType = "node"
 )
 
 type InvokeModelRequest struct {
 	BaseInvokeDifyRequest
-	Provider   string         `json:"provider"`
-	Model      string         `json:"model"`
-	Parameters map[string]any `json:"parameters"`
+	Provider   string                   `json:"provider"`
+	Model      string                   `json:"model"`
+	ModelType  model_entities.ModelType `json:"model_type"`
+	Parameters map[string]any           `json:"parameters"`
 }
 
 func (r *InvokeModelRequest) FromMap(base map[string]any, data map[string]any) error {
@@ -51,6 +56,10 @@ func (r *InvokeModelRequest) FromMap(base map[string]any, data map[string]any) e
 		return fmt.Errorf("model is not a string")
 	}
 
+	if r.ModelType, ok = data["model_type"].(model_entities.ModelType); !ok {
+		return fmt.Errorf("model_type is not a string")
+	}
+
 	if r.Parameters, ok = data["parameters"].(map[string]any); !ok {
 		return fmt.Errorf("parameters is not a map")
 	}
@@ -110,13 +119,13 @@ type InvokeToolResponseChunk struct {
 
 type InvokeNodeRequest[T WorkflowNodeData] struct {
 	BaseInvokeDifyRequest
-	NodeType string `json:"node_type"`
-	NodeData T      `json:"node_data"`
+	NodeType NodeType `json:"node_type"`
+	NodeData T        `json:"node_data"`
 }
 
 func (r *InvokeNodeRequest[T]) FromMap(data map[string]any) error {
 	var ok bool
-	if r.NodeType, ok = data["node_type"].(string); !ok {
+	if r.NodeType, ok = data["node_type"].(NodeType); !ok {
 		return fmt.Errorf("node_type is not a string")
 	}
 

+ 6 - 4
internal/core/dify_invocation/workflow_node_data.go

@@ -6,11 +6,13 @@ type WorkflowNodeData interface {
 	*KnowledgeRetrievalNodeData | *QuestionClassifierNodeData | *ParameterExtractorNodeData | *CodeNodeData
 }
 
+type NodeType string
+
 const (
-	NODE_TYPE_KNOWLEDGE_RETRIEVAL = "knowledge_retrieval"
-	NODE_TYPE_QUESTION_CLASSIFIER = "question_classifier"
-	NODE_TYPE_PARAMETER_EXTRACTOR = "parameter_extractor"
-	NODE_TYPE_CODE                = "code"
+	KNOWLEDGE_RETRIEVAL NodeType = "knowledge_retrieval"
+	QUESTION_CLASSIFIER NodeType = "question_classifier"
+	PARAMETER_EXTRACTOR NodeType = "parameter_extractor"
+	CODE                NodeType = "code"
 )
 
 type KnowledgeRetrievalNodeData struct {

+ 9 - 9
internal/core/plugin_daemon/invoke_dify.go

@@ -52,7 +52,7 @@ func invokeDify(runtime entities.PluginRuntimeInterface,
 		}
 		submitModelTask(runtime, session, request_id, &r)
 	case "node":
-		node_type, ok := detailed_request["node_type"].(string)
+		node_type, ok := detailed_request["node_type"].(dify_invocation.NodeType)
 		if !ok {
 			return fmt.Errorf("invoke request missing node_type: %s", data)
 		}
@@ -61,36 +61,36 @@ func invokeDify(runtime entities.PluginRuntimeInterface,
 			return fmt.Errorf("invoke request missing data: %s", data)
 		}
 		switch node_type {
-		case dify_invocation.NODE_TYPE_QUESTION_CLASSIFIER:
+		case dify_invocation.QUESTION_CLASSIFIER:
 			d := dify_invocation.InvokeNodeRequest[*dify_invocation.QuestionClassifierNodeData]{
-				NodeType: dify_invocation.NODE_TYPE_QUESTION_CLASSIFIER,
+				NodeType: dify_invocation.QUESTION_CLASSIFIER,
 				NodeData: &dify_invocation.QuestionClassifierNodeData{},
 			}
 			if err := d.FromMap(node_data); err != nil {
 				return fmt.Errorf("unmarshal question classifier node data failed: %s", err.Error())
 			}
 			submitNodeInvocationRequestTask(runtime, session, request_id, &d)
-		case dify_invocation.NODE_TYPE_KNOWLEDGE_RETRIEVAL:
+		case dify_invocation.KNOWLEDGE_RETRIEVAL:
 			d := dify_invocation.InvokeNodeRequest[*dify_invocation.KnowledgeRetrievalNodeData]{
-				NodeType: dify_invocation.NODE_TYPE_KNOWLEDGE_RETRIEVAL,
+				NodeType: dify_invocation.KNOWLEDGE_RETRIEVAL,
 				NodeData: &dify_invocation.KnowledgeRetrievalNodeData{},
 			}
 			if err := d.FromMap(node_data); err != nil {
 				return fmt.Errorf("unmarshal knowledge retrieval node data failed: %s", err.Error())
 			}
 			submitNodeInvocationRequestTask(runtime, session, request_id, &d)
-		case dify_invocation.NODE_TYPE_PARAMETER_EXTRACTOR:
+		case dify_invocation.PARAMETER_EXTRACTOR:
 			d := dify_invocation.InvokeNodeRequest[*dify_invocation.ParameterExtractorNodeData]{
-				NodeType: dify_invocation.NODE_TYPE_PARAMETER_EXTRACTOR,
+				NodeType: dify_invocation.PARAMETER_EXTRACTOR,
 				NodeData: &dify_invocation.ParameterExtractorNodeData{},
 			}
 			if err := d.FromMap(node_data); err != nil {
 				return fmt.Errorf("unmarshal parameter extractor node data failed: %s", err.Error())
 			}
 			submitNodeInvocationRequestTask(runtime, session, request_id, &d)
-		case dify_invocation.NODE_TYPE_CODE:
+		case dify_invocation.CODE:
 			d := dify_invocation.InvokeNodeRequest[*dify_invocation.CodeNodeData]{
-				NodeType: dify_invocation.NODE_TYPE_CODE,
+				NodeType: dify_invocation.CODE,
 				NodeData: &dify_invocation.CodeNodeData{},
 			}
 			if err := d.FromMap(node_data); err != nil {

+ 5 - 3
internal/types/app/config.go

@@ -11,7 +11,7 @@ type Config struct {
 
 	StoragePath string `envconfig:"STORAGE_PATH"`
 
-	Platform string `envconfig:"PLATFORM"`
+	Platform PlatformType `envconfig:"PLATFORM"`
 
 	RoutinePoolSize int `envconfig:"ROUTINE_POOL_SIZE"`
 
@@ -26,7 +26,9 @@ type Config struct {
 	DifyInvocationConnectionIdleTimeout int `envconfig:"DIFY_INVOCATION_CONNECTION_IDLE_TIMEOUT"`
 }
 
+type PlatformType string
+
 const (
-	PLATFORM_LOCAL      = "local"
-	PLATFORM_AWS_LAMBDA = "aws_lambda"
+	PLATFORM_LOCAL      PlatformType = "local"
+	PLATFORM_AWS_LAMBDA PlatformType = "aws_lambda"
 )

+ 10 - 7
internal/types/entities/config.go

@@ -1,17 +1,20 @@
 package entities
 
 import (
+	"time"
+
 	"github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
 )
 
 type PluginConfiguration struct {
-	Version  string                      `json:"version"`
-	Author   string                      `json:"author"`
-	Name     string                      `json:"name"`
-	Datetime int64                       `json:"datetime"`
-	Module   string                      `json:"module"`
-	Resource PluginConfigurationResource `json:"resource"`
-	Meta     PluginConfigurationMeta     `json:"meta"`
+	Version   string                      `json:"version"`
+	Author    string                      `json:"author"`
+	Name      string                      `json:"name"`
+	CreatedAt time.Time                   `json:"createdAt"`
+	Module    string                      `json:"module"`
+	Resource  PluginConfigurationResource `json:"resource"`
+	Meta      PluginConfigurationMeta     `json:"meta"`
+	Plugins   []string                    `json:"plugins"`
 }
 
 func (p *PluginConfiguration) Identity() string {

+ 16 - 0
internal/types/entities/model_entities/llm.go

@@ -0,0 +1,16 @@
+package model_entities
+
+type ModelType string
+
+const (
+	MODEL_TYPE_LLM            ModelType = "llm"
+	MODEL_TYPE_TEXT_EMBEDDING ModelType = "text_embedding"
+	MODEL_TYPE_RERANKING      ModelType = "rerank"
+)
+
+type LLMModel string
+
+const (
+	LLM_MODE_CHAT       LLMModel = "chat"
+	LLM_MODE_COMPLETION LLMModel = "completion"
+)

+ 7 - 0
internal/types/entities/plugin_entities/common.go

@@ -0,0 +1,7 @@
+package plugin_entities
+
+type I18nObject struct {
+	ZhHans string `json:"zh_Hans"`
+	EnUS   string `json:"en_US"`
+	PtBr   string `json:"pt_BR"`
+}

+ 13 - 9
internal/types/entities/plugin_entities/event.go

@@ -3,15 +3,17 @@ package plugin_entities
 import "encoding/json"
 
 type PluginUniversalEvent struct {
-	Event     string          `json:"event"`
+	Event     PluginEventType `json:"event"`
 	SessionId string          `json:"session_id"`
 	Data      json.RawMessage `json:"data"`
 }
 
+type PluginEventType string
+
 const (
-	PLUGIN_EVENT_LOG     = "log"
-	PLUGIN_EVENT_SESSION = "session"
-	PLUGIN_EVENT_ERROR   = "error"
+	PLUGIN_EVENT_LOG     PluginEventType = "log"
+	PLUGIN_EVENT_SESSION PluginEventType = "session"
+	PLUGIN_EVENT_ERROR   PluginEventType = "error"
 )
 
 type PluginLogEvent struct {
@@ -21,14 +23,16 @@ type PluginLogEvent struct {
 }
 
 type SessionMessage struct {
-	Type string          `json:"type"`
-	Data json.RawMessage `json:"data"`
+	Type SESSION_MESSAGE_TYPE `json:"type"`
+	Data json.RawMessage      `json:"data"`
 }
 
+type SESSION_MESSAGE_TYPE string
+
 const (
-	SESSION_MESSAGE_TYPE_STREAM = "stream"
-	SESSION_MESSAGE_TYPE_END    = "end"
-	SESSION_MESSAGE_TYPE_INVOKE = "invoke"
+	SESSION_MESSAGE_TYPE_STREAM SESSION_MESSAGE_TYPE = "stream"
+	SESSION_MESSAGE_TYPE_END    SESSION_MESSAGE_TYPE = "end"
+	SESSION_MESSAGE_TYPE_INVOKE SESSION_MESSAGE_TYPE = "invoke"
 )
 
 type InvokeToolResponseChunk struct {

+ 0 - 20
internal/types/entities/plugin_entities/registration.go

@@ -1,20 +0,0 @@
-package plugin_entities
-
-type PluginRegistration struct {
-	PluginName    string                      `json:"plugin_name"`
-	PluginVersion string                      `json:"plugin_version"`
-	Models        []ModelProviderRegistration `json:"models"`
-	Tools         []ToolProviderRegistration  `json:"tools"`
-}
-
-type ToolProviderRegistration struct {
-}
-
-type ToolRegistration struct {
-}
-
-type ModelProviderRegistration struct {
-}
-
-type ModelRegistration struct {
-}

+ 118 - 0
internal/types/entities/plugin_entities/tool_configuration.go

@@ -0,0 +1,118 @@
+package plugin_entities
+
+type ToolIdentity struct {
+	Author string     `json:"author"`
+	Name   string     `json:"name"`
+	Label  I18nObject `json:"label"`
+}
+
+type ToolParameterOption struct {
+	Value string     `json:"value"`
+	Label I18nObject `json:"label"`
+}
+
+type ToolParameterType string
+
+const (
+	TOOL_PARAMETER_TYPE_STRING       ToolParameterType = "string"
+	TOOL_PARAMETER_TYPE_NUMBER       ToolParameterType = "number"
+	TOOL_PARAMETER_TYPE_BOOLEAN      ToolParameterType = "boolean"
+	TOOL_PARAMETER_TYPE_SELECT       ToolParameterType = "select"
+	TOOL_PARAMETER_TYPE_SECRET_INPUT ToolParameterType = "secret_input"
+	TOOL_PARAMETER_TYPE_FILE         ToolParameterType = "file"
+)
+
+type ToolParameterForm string
+
+const (
+	TOOL_PARAMETER_FORM_SCHEMA ToolParameterForm = "schema"
+	TOOL_PARAMETER_FORM_FORM   ToolParameterForm = "form"
+	TOOL_PARAMETER_FORM_LLM    ToolParameterForm = "llm"
+)
+
+type ToolParameter struct {
+	Name             string                `json:"name"`
+	Label            I18nObject            `json:"label"`
+	HumanDescription I18nObject            `json:"human_description"`
+	Type             ToolParameterType     `json:"type"`
+	Form             ToolParameterForm     `json:"form"`
+	LLMDescription   string                `json:"llm_description"`
+	Required         bool                  `json:"required"`
+	Default          any                   `json:"default"`
+	Min              *float64              `json:"min"`
+	Max              *float64              `json:"max"`
+	Options          []ToolParameterOption `json:"options"`
+}
+
+type ToolDescription struct {
+	Human I18nObject `json:"human"`
+	LLM   string     `json:"llm"`
+}
+
+type ToolConfiguration struct {
+	Identity    ToolIdentity    `json:"identity"`
+	Description ToolDescription `json:"description"`
+	Parameters  []ToolParameter `json:"parameters"`
+}
+
+type ToolCredentialsOption struct {
+	Value string     `json:"value"`
+	Label I18nObject `json:"label"`
+}
+
+type CredentialType string
+
+const (
+	CREDENTIALS_TYPE_SECRET_INPUT CredentialType = "secret_input"
+	CREDENTIALS_TYPE_TEXT_INPUT   CredentialType = "text_input"
+	CREDENTIALS_TYPE_SELECT       CredentialType = "select"
+	CREDENTIALS_TYPE_BOOLEAN      CredentialType = "boolean"
+)
+
+type ToolProviderCredential struct {
+	Name        string                  `json:"name"`
+	Type        CredentialType          `json:"type"`
+	Required    bool                    `json:"required"`
+	Default     any                     `json:"default"`
+	Options     []ToolCredentialsOption `json:"options"`
+	Label       I18nObject              `json:"label"`
+	Helper      *I18nObject             `json:"helper"`
+	URL         *string                 `json:"url"`
+	Placeholder *I18nObject             `json:"placeholder"`
+}
+
+type ToolLabel string
+
+const (
+	TOOL_LABEL_SEARCH        ToolLabel = "search"
+	TOOL_LABEL_IMAGE         ToolLabel = "image"
+	TOOL_LABEL_VIDEOS        ToolLabel = "videos"
+	TOOL_LABEL_WEATHER       ToolLabel = "weather"
+	TOOL_LABEL_FINANCE       ToolLabel = "finance"
+	TOOL_LABEL_DESIGN        ToolLabel = "design"
+	TOOL_LABEL_TRAVEL        ToolLabel = "travel"
+	TOOL_LABEL_SOCIAL        ToolLabel = "social"
+	TOOL_LABEL_NEWS          ToolLabel = "news"
+	TOOL_LABEL_MEDICAL       ToolLabel = "medical"
+	TOOL_LABEL_PRODUCTIVITY  ToolLabel = "productivity"
+	TOOL_LABEL_EDUCATION     ToolLabel = "education"
+	TOOL_LABEL_BUSINESS      ToolLabel = "business"
+	TOOL_LABEL_ENTERTAINMENT ToolLabel = "entertainment"
+	TOOL_LABEL_UTILITIES     ToolLabel = "utilities"
+	TOOL_LABEL_OTHER         ToolLabel = "other"
+)
+
+type ToolProviderIdentity struct {
+	Author      string      `json:"author"`
+	Name        string      `json:"name"`
+	Description I18nObject  `json:"description"`
+	Icon        []byte      `json:"icon"`
+	Label       I18nObject  `json:"label"`
+	Tags        []ToolLabel `json:"tags"`
+}
+
+type ToolProviderConfiguration struct {
+	Identity          ToolProviderIdentity              `json:"identity"`
+	CredentialsSchema map[string]ToolProviderCredential `json:"credentials_schema"`
+	Tools             []ToolConfiguration               `json:"tools"`
+}