瀏覽代碼

feat: backwards invoke llm

Yeuoly 1 年之前
父節點
當前提交
d1ab9878f5

+ 2 - 1
go.mod

@@ -5,6 +5,7 @@ go 1.20
 require (
 	github.com/google/uuid v1.6.0
 	github.com/redis/go-redis/v9 v9.5.3
+	gorm.io/gorm v1.25.11
 )
 
 require (
@@ -16,7 +17,7 @@ require (
 	github.com/jackc/puddle/v2 v2.2.1 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
-	gorm.io/gorm v1.25.11 // indirect
+	github.com/rogpeppe/go-internal v1.12.0 // indirect
 )
 
 require (

+ 5 - 2
go.sum

@@ -58,6 +58,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02
 github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
 github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
 github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
 github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -80,6 +82,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU=
 github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
 github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
 github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -100,7 +104,6 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E
 github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
@@ -125,8 +128,8 @@ golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
 golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
 google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
 google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
 gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 15 - 29
internal/core/dify_invocation/types.go

@@ -13,7 +13,7 @@ type BaseInvokeDifyRequest struct {
 type InvokeType string
 
 const (
-	INVOKE_TYPE_LLM            InvokeType = "LLM"
+	INVOKE_TYPE_LLM            InvokeType = "llm"
 	INVOKE_TYPE_TEXT_EMBEDDING InvokeType = "text_embedding"
 	INVOKE_TYPE_RERANK         InvokeType = "rerank"
 	INVOKE_TYPE_TTS            InvokeType = "tts"
@@ -25,58 +25,44 @@ const (
 
 type InvokeLLMRequest struct {
 	BaseInvokeDifyRequest
-	Data struct {
-		requests.BaseRequestInvokeModel
-		requests.InvokeLLMSchema
-	} `json:"data" validate:"required"`
+	requests.BaseRequestInvokeModel
+	requests.InvokeLLMSchema
 }
 
 type InvokeTextEmbeddingRequest struct {
 	BaseInvokeDifyRequest
-	Data struct {
-		requests.BaseRequestInvokeModel
-		requests.InvokeTextEmbeddingSchema
-	} `json:"data" validate:"required"`
+	requests.BaseRequestInvokeModel
+	requests.InvokeTextEmbeddingSchema
 }
 
 type InvokeRerankRequest struct {
 	BaseInvokeDifyRequest
-	Data struct {
-		requests.BaseRequestInvokeModel
-		requests.InvokeRerankSchema
-	} `json:"data" validate:"required"`
+	requests.BaseRequestInvokeModel
+	requests.InvokeRerankSchema
 }
 
 type InvokeTTSRequest struct {
 	BaseInvokeDifyRequest
-	Data struct {
-		requests.BaseRequestInvokeModel
-		requests.InvokeTTSSchema
-	} `json:"data" validate:"required"`
+	requests.BaseRequestInvokeModel
+	requests.InvokeTTSSchema
 }
 
 type InvokeSpeech2TextRequest struct {
 	BaseInvokeDifyRequest
-	Data struct {
-		requests.BaseRequestInvokeModel
-		requests.InvokeSpeech2TextSchema
-	} `json:"data" validate:"required"`
+	requests.BaseRequestInvokeModel
+	requests.InvokeSpeech2TextSchema
 }
 
 type InvokeModerationRequest struct {
 	BaseInvokeDifyRequest
-	Data struct {
-		requests.BaseRequestInvokeModel
-		requests.InvokeModerationSchema
-	} `json:"data" validate:"required"`
+	requests.BaseRequestInvokeModel
+	requests.InvokeModerationSchema
 }
 
 type InvokeToolRequest struct {
 	BaseInvokeDifyRequest
-	Data struct {
-		ToolType requests.ToolType `json:"tool_type" validate:"required,tool_type"`
-		requests.InvokeToolSchema
-	} `json:"data" validate:"required"`
+	ToolType requests.ToolType `json:"tool_type" validate:"required,tool_type"`
+	requests.InvokeToolSchema
 }
 
 type InvokeNodeResponse struct {

+ 23 - 0
internal/core/plugin_daemon/backwards_invocation/basic.go

@@ -0,0 +1,23 @@
+package backwards_invocation
+
+type PluginAccessType string
+
+const (
+	PLUGIN_ACCESS_TYPE_TOOL  PluginAccessType = "tool"
+	PLUGIN_ACCESS_TYPE_MODEL PluginAccessType = "model"
+)
+
+type PluginAccessAction string
+
+const (
+	PLUGIN_ACCESS_ACTION_INVOKE_TOOL                   PluginAccessAction = "invoke_tool"
+	PLUGIN_ACCESS_ACTION_VALIDATE_TOOL_CREDENTIALS     PluginAccessAction = "validate_tool_credentials"
+	PLUGIN_ACCESS_ACTION_INVOKE_LLM                    PluginAccessAction = "invoke_llm"
+	PLUGIN_ACCESS_ACTION_INVOKE_TEXT_EMBEDDING         PluginAccessAction = "invoke_text_embedding"
+	PLUGIN_ACCESS_ACTION_INVOKE_RERANK                 PluginAccessAction = "invoke_rerank"
+	PLUGIN_ACCESS_ACTION_INVOKE_TTS                    PluginAccessAction = "invoke_tts"
+	PLUGIN_ACCESS_ACTION_INVOKE_SPEECH2TEXT            PluginAccessAction = "invoke_speech2text"
+	PLUGIN_ACCESS_ACTION_INVOKE_MODERATION             PluginAccessAction = "invoke_moderation"
+	PLUGIN_ACCESS_ACTION_VALIDATE_PROVIDER_CREDENTIALS PluginAccessAction = "validate_provider_credentials"
+	PLUGIN_ACCESS_ACTION_VALIDATE_MODEL_CREDENTIALS    PluginAccessAction = "validate_model_credentials"
+)

+ 5 - 5
internal/core/plugin_daemon/backwards_invocation/entities.go

@@ -9,13 +9,13 @@ const (
 )
 
 type BackwardsInvocationResponseEvent struct {
-	BackwardsRequestId string         `json:"backwards_request_id"`
-	Event              RequestEvent   `json:"event"`
-	Message            string         `json:"message"`
-	Data               map[string]any `json:"data"`
+	BackwardsRequestId string       `json:"backwards_request_id"`
+	Event              RequestEvent `json:"event"`
+	Message            string       `json:"message"`
+	Data               any          `json:"data"`
 }
 
-func NewResponseEvent(request_id string, message string, data map[string]any) *BackwardsInvocationResponseEvent {
+func NewResponseEvent(request_id string, message string, data any) *BackwardsInvocationResponseEvent {
 	return &BackwardsInvocationResponseEvent{
 		BackwardsRequestId: request_id,
 		Event:              REQUEST_EVENT_RESPONSE,

+ 1 - 2
internal/core/plugin_daemon/backwards_invocation/request.go

@@ -5,7 +5,6 @@ import (
 
 	"github.com/langgenius/dify-plugin-daemon/internal/core/dify_invocation"
 	"github.com/langgenius/dify-plugin-daemon/internal/core/session_manager"
-	"github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
 )
 
 type BackwardsInvocationType = dify_invocation.InvokeType
@@ -43,7 +42,7 @@ func (bi *BackwardsInvocation) WriteError(err error) {
 func (bi *BackwardsInvocation) WriteResponse(message string, data any) {
 	bi.session.Write(
 		session_manager.PLUGIN_IN_STREAM_EVENT_RESPONSE,
-		NewResponseEvent(bi.id, message, parser.StructToMap(data)),
+		NewResponseEvent(bi.id, message, data),
 	)
 }
 

+ 66 - 24
internal/core/plugin_daemon/invoke_dify.go

@@ -1,18 +1,18 @@
-package plugin_daemon
+package backwards_invocation
 
 import (
 	"fmt"
 
 	"github.com/langgenius/dify-plugin-daemon/internal/core/dify_invocation"
-	"github.com/langgenius/dify-plugin-daemon/internal/core/plugin_daemon/backwards_invocation"
 	"github.com/langgenius/dify-plugin-daemon/internal/core/session_manager"
 	"github.com/langgenius/dify-plugin-daemon/internal/types/entities"
+	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/model_entities"
 	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/tool_entities"
 	"github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
 	"github.com/langgenius/dify-plugin-daemon/internal/utils/routine"
 )
 
-func invokeDify(
+func InvokeDify(
 	runtime entities.PluginRuntimeInterface,
 	invoke_from PluginAccessType,
 	session *session_manager.Session, data []byte,
@@ -48,7 +48,7 @@ func invokeDify(
 	return nil
 }
 
-func prepareDifyInvocationArguments(session *session_manager.Session, request map[string]any) (*backwards_invocation.BackwardsInvocation, error) {
+func prepareDifyInvocationArguments(session *session_manager.Session, request map[string]any) (*BackwardsInvocation, error) {
 	typ, ok := request["type"].(string)
 	if !ok {
 		return nil, fmt.Errorf("invoke request missing type: %s", request)
@@ -66,42 +66,42 @@ func prepareDifyInvocationArguments(session *session_manager.Session, request ma
 		return nil, fmt.Errorf("invoke request missing request: %s", request)
 	}
 
-	return backwards_invocation.NewBackwardsInvocation(
-		backwards_invocation.BackwardsInvocationType(typ),
+	return NewBackwardsInvocation(
+		BackwardsInvocationType(typ),
 		backwards_request_id, session, detailed_request,
 	), nil
 }
 
 var (
-	dispatchMapping = map[dify_invocation.InvokeType]func(handle *backwards_invocation.BackwardsInvocation){
-		dify_invocation.INVOKE_TYPE_TOOL: func(handle *backwards_invocation.BackwardsInvocation) {
+	dispatchMapping = map[dify_invocation.InvokeType]func(handle *BackwardsInvocation){
+		dify_invocation.INVOKE_TYPE_TOOL: func(handle *BackwardsInvocation) {
 			genericDispatchTask[dify_invocation.InvokeToolRequest](handle, executeDifyInvocationToolTask)
 		},
-		dify_invocation.INVOKE_TYPE_LLM: func(handle *backwards_invocation.BackwardsInvocation) {
+		dify_invocation.INVOKE_TYPE_LLM: func(handle *BackwardsInvocation) {
 			genericDispatchTask[dify_invocation.InvokeLLMRequest](handle, executeDifyInvocationLLMTask)
 		},
-		dify_invocation.INVOKE_TYPE_TEXT_EMBEDDING: func(handle *backwards_invocation.BackwardsInvocation) {
+		dify_invocation.INVOKE_TYPE_TEXT_EMBEDDING: func(handle *BackwardsInvocation) {
 			genericDispatchTask[dify_invocation.InvokeTextEmbeddingRequest](handle, executeDifyInvocationTextEmbeddingTask)
 		},
-		dify_invocation.INVOKE_TYPE_RERANK: func(handle *backwards_invocation.BackwardsInvocation) {
+		dify_invocation.INVOKE_TYPE_RERANK: func(handle *BackwardsInvocation) {
 			genericDispatchTask[dify_invocation.InvokeRerankRequest](handle, executeDifyInvocationRerankTask)
 		},
-		dify_invocation.INVOKE_TYPE_TTS: func(handle *backwards_invocation.BackwardsInvocation) {
+		dify_invocation.INVOKE_TYPE_TTS: func(handle *BackwardsInvocation) {
 			genericDispatchTask[dify_invocation.InvokeTTSRequest](handle, executeDifyInvocationTTSTask)
 		},
-		dify_invocation.INVOKE_TYPE_SPEECH2TEXT: func(handle *backwards_invocation.BackwardsInvocation) {
+		dify_invocation.INVOKE_TYPE_SPEECH2TEXT: func(handle *BackwardsInvocation) {
 			genericDispatchTask[dify_invocation.InvokeSpeech2TextRequest](handle, executeDifyInvocationSpeech2TextTask)
 		},
-		dify_invocation.INVOKE_TYPE_MODERATION: func(handle *backwards_invocation.BackwardsInvocation) {
+		dify_invocation.INVOKE_TYPE_MODERATION: func(handle *BackwardsInvocation) {
 			genericDispatchTask[dify_invocation.InvokeModerationRequest](handle, executeDifyInvocationModerationTask)
 		},
 	}
 )
 
 func genericDispatchTask[T any](
-	handle *backwards_invocation.BackwardsInvocation,
+	handle *BackwardsInvocation,
 	dispatch func(
-		handle *backwards_invocation.BackwardsInvocation,
+		handle *BackwardsInvocation,
 		request *T,
 	),
 ) {
@@ -113,7 +113,7 @@ func genericDispatchTask[T any](
 	dispatch(handle, r)
 }
 
-func dispatchDifyInvocationTask(handle *backwards_invocation.BackwardsInvocation) {
+func dispatchDifyInvocationTask(handle *BackwardsInvocation) {
 	request_data := handle.RequestData()
 	tenant_id, err := handle.TenantID()
 	if err != nil {
@@ -127,6 +127,8 @@ func dispatchDifyInvocationTask(handle *backwards_invocation.BackwardsInvocation
 		return
 	}
 	request_data["user_id"] = user_id
+	typ := handle.Type()
+	request_data["type"] = typ
 
 	for t, v := range dispatchMapping {
 		if t == handle.Type() {
@@ -139,7 +141,7 @@ func dispatchDifyInvocationTask(handle *backwards_invocation.BackwardsInvocation
 }
 
 func executeDifyInvocationToolTask(
-	handle *backwards_invocation.BackwardsInvocation,
+	handle *BackwardsInvocation,
 	request *dify_invocation.InvokeToolRequest,
 ) {
 	response, err := dify_invocation.InvokeTool(request)
@@ -154,43 +156,83 @@ func executeDifyInvocationToolTask(
 }
 
 func executeDifyInvocationLLMTask(
-	handle *backwards_invocation.BackwardsInvocation,
+	handle *BackwardsInvocation,
 	request *dify_invocation.InvokeLLMRequest,
 ) {
+	response, err := dify_invocation.InvokeLLM(request)
+	if err != nil {
+		handle.WriteError(fmt.Errorf("invoke llm model failed: %s", err.Error()))
+		return
+	}
 
+	response.Wrap(func(t model_entities.LLMResultChunk) {
+		handle.WriteResponse("stream", t)
+	})
 }
 
 func executeDifyInvocationTextEmbeddingTask(
-	handle *backwards_invocation.BackwardsInvocation,
+	handle *BackwardsInvocation,
 	request *dify_invocation.InvokeTextEmbeddingRequest,
 ) {
+	response, err := dify_invocation.InvokeTextEmbedding(request)
+	if err != nil {
+		handle.WriteError(fmt.Errorf("invoke text-embedding model failed: %s", err.Error()))
+		return
+	}
 
+	handle.WriteResponse("struct", response)
 }
 
 func executeDifyInvocationRerankTask(
-	handle *backwards_invocation.BackwardsInvocation,
+	handle *BackwardsInvocation,
 	request *dify_invocation.InvokeRerankRequest,
 ) {
+	response, err := dify_invocation.InvokeRerank(request)
+	if err != nil {
+		handle.WriteError(fmt.Errorf("invoke rerank model failed: %s", err.Error()))
+		return
+	}
 
+	handle.WriteResponse("struct", response)
 }
 
 func executeDifyInvocationTTSTask(
-	handle *backwards_invocation.BackwardsInvocation,
+	handle *BackwardsInvocation,
 	request *dify_invocation.InvokeTTSRequest,
 ) {
+	response, err := dify_invocation.InvokeTTS(request)
+	if err != nil {
+		handle.WriteError(fmt.Errorf("invoke tts model failed: %s", err.Error()))
+		return
+	}
 
+	response.Wrap(func(t model_entities.TTSResult) {
+		handle.WriteResponse("struct", t)
+	})
 }
 
 func executeDifyInvocationSpeech2TextTask(
-	handle *backwards_invocation.BackwardsInvocation,
+	handle *BackwardsInvocation,
 	request *dify_invocation.InvokeSpeech2TextRequest,
 ) {
+	response, err := dify_invocation.InvokeSpeech2Text(request)
+	if err != nil {
+		handle.WriteError(fmt.Errorf("invoke speech2text model failed: %s", err.Error()))
+		return
+	}
 
+	handle.WriteResponse("struct", response)
 }
 
 func executeDifyInvocationModerationTask(
-	handle *backwards_invocation.BackwardsInvocation,
+	handle *BackwardsInvocation,
 	request *dify_invocation.InvokeModerationRequest,
 ) {
+	response, err := dify_invocation.InvokeModeration(request)
+	if err != nil {
+		handle.WriteError(fmt.Errorf("invoke moderation model failed: %s", err.Error()))
+		return
+	}
 
+	handle.WriteResponse("struct", response)
 }

+ 2 - 22
internal/core/plugin_daemon/basic.go

@@ -1,28 +1,8 @@
 package plugin_daemon
 
-type PluginAccessType string
+import "github.com/langgenius/dify-plugin-daemon/internal/core/plugin_daemon/backwards_invocation"
 
-const (
-	PLUGIN_ACCESS_TYPE_TOOL  PluginAccessType = "tool"
-	PLUGIN_ACCESS_TYPE_MODEL PluginAccessType = "model"
-)
-
-type PluginAccessAction string
-
-const (
-	PLUGIN_ACCESS_ACTION_INVOKE_TOOL                   PluginAccessAction = "invoke_tool"
-	PLUGIN_ACCESS_ACTION_VALIDATE_TOOL_CREDENTIALS     PluginAccessAction = "validate_tool_credentials"
-	PLUGIN_ACCESS_ACTION_INVOKE_LLM                    PluginAccessAction = "invoke_llm"
-	PLUGIN_ACCESS_ACTION_INVOKE_TEXT_EMBEDDING         PluginAccessAction = "invoke_text_embedding"
-	PLUGIN_ACCESS_ACTION_INVOKE_RERANK                 PluginAccessAction = "invoke_rerank"
-	PLUGIN_ACCESS_ACTION_INVOKE_TTS                    PluginAccessAction = "invoke_tts"
-	PLUGIN_ACCESS_ACTION_INVOKE_SPEECH2TEXT            PluginAccessAction = "invoke_speech2text"
-	PLUGIN_ACCESS_ACTION_INVOKE_MODERATION             PluginAccessAction = "invoke_moderation"
-	PLUGIN_ACCESS_ACTION_VALIDATE_PROVIDER_CREDENTIALS PluginAccessAction = "validate_provider_credentials"
-	PLUGIN_ACCESS_ACTION_VALIDATE_MODEL_CREDENTIALS    PluginAccessAction = "validate_model_credentials"
-)
-
-func getBasicPluginAccessMap(user_id string, access_type PluginAccessType, action PluginAccessAction) map[string]any {
+func getBasicPluginAccessMap(user_id string, access_type backwards_invocation.PluginAccessType, action backwards_invocation.PluginAccessAction) map[string]any {
 	return map[string]any{
 		"user_id": user_id,
 		"type":    access_type,

+ 22 - 21
internal/core/plugin_daemon/model_service.go

@@ -3,6 +3,7 @@ package plugin_daemon
 import (
 	"errors"
 
+	"github.com/langgenius/dify-plugin-daemon/internal/core/plugin_daemon/backwards_invocation"
 	"github.com/langgenius/dify-plugin-daemon/internal/core/plugin_manager"
 	"github.com/langgenius/dify-plugin-daemon/internal/core/session_manager"
 	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/model_entities"
@@ -17,8 +18,8 @@ func genericInvokePlugin[Req any, Rsp any](
 	session *session_manager.Session,
 	request *Req,
 	response_buffer_size int,
-	typ PluginAccessType,
-	action PluginAccessAction,
+	typ backwards_invocation.PluginAccessType,
+	action backwards_invocation.PluginAccessAction,
 ) (
 	*stream.StreamResponse[Rsp], error,
 ) {
@@ -46,7 +47,7 @@ func genericInvokePlugin[Req any, Rsp any](
 			}
 			response.Write(chunk)
 		case plugin_entities.SESSION_MESSAGE_TYPE_INVOKE:
-			if err := invokeDify(runtime, typ, session, chunk.Data); err != nil {
+			if err := backwards_invocation.InvokeDify(runtime, typ, session, chunk.Data); err != nil {
 				log.Error("invoke dify failed: %s", err.Error())
 				return
 			}
@@ -84,8 +85,8 @@ func genericInvokePlugin[Req any, Rsp any](
 
 func getInvokeModelMap(
 	session *session_manager.Session,
-	typ PluginAccessType,
-	action PluginAccessAction,
+	typ backwards_invocation.PluginAccessType,
+	action backwards_invocation.PluginAccessAction,
 	request any,
 ) map[string]any {
 	req := getBasicPluginAccessMap(session.UserID(), typ, action)
@@ -105,8 +106,8 @@ func InvokeLLM(
 		session,
 		request,
 		512,
-		PLUGIN_ACCESS_TYPE_MODEL,
-		PLUGIN_ACCESS_ACTION_INVOKE_LLM,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_MODEL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_INVOKE_LLM,
 	)
 }
 
@@ -120,8 +121,8 @@ func InvokeTextEmbedding(
 		session,
 		request,
 		1,
-		PLUGIN_ACCESS_TYPE_MODEL,
-		PLUGIN_ACCESS_ACTION_INVOKE_TEXT_EMBEDDING,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_MODEL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_INVOKE_TEXT_EMBEDDING,
 	)
 }
 
@@ -135,8 +136,8 @@ func InvokeRerank(
 		session,
 		request,
 		1,
-		PLUGIN_ACCESS_TYPE_MODEL,
-		PLUGIN_ACCESS_ACTION_INVOKE_RERANK,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_MODEL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_INVOKE_RERANK,
 	)
 }
 
@@ -150,8 +151,8 @@ func InvokeTTS(
 		session,
 		request,
 		1,
-		PLUGIN_ACCESS_TYPE_MODEL,
-		PLUGIN_ACCESS_ACTION_INVOKE_TTS,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_MODEL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_INVOKE_TTS,
 	)
 }
 
@@ -165,8 +166,8 @@ func InvokeSpeech2Text(
 		session,
 		request,
 		1,
-		PLUGIN_ACCESS_TYPE_MODEL,
-		PLUGIN_ACCESS_ACTION_INVOKE_SPEECH2TEXT,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_MODEL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_INVOKE_SPEECH2TEXT,
 	)
 }
 
@@ -180,8 +181,8 @@ func InvokeModeration(
 		session,
 		request,
 		1,
-		PLUGIN_ACCESS_TYPE_MODEL,
-		PLUGIN_ACCESS_ACTION_INVOKE_MODERATION,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_MODEL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_INVOKE_MODERATION,
 	)
 }
 
@@ -195,8 +196,8 @@ func ValidateProviderCredentials(
 		session,
 		request,
 		1,
-		PLUGIN_ACCESS_TYPE_MODEL,
-		PLUGIN_ACCESS_ACTION_VALIDATE_PROVIDER_CREDENTIALS,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_MODEL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_VALIDATE_PROVIDER_CREDENTIALS,
 	)
 }
 
@@ -210,7 +211,7 @@ func ValidateModelCredentials(
 		session,
 		request,
 		1,
-		PLUGIN_ACCESS_TYPE_MODEL,
-		PLUGIN_ACCESS_ACTION_VALIDATE_MODEL_CREDENTIALS,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_MODEL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_VALIDATE_MODEL_CREDENTIALS,
 	)
 }

+ 5 - 4
internal/core/plugin_daemon/tool_service.go

@@ -1,6 +1,7 @@
 package plugin_daemon
 
 import (
+	"github.com/langgenius/dify-plugin-daemon/internal/core/plugin_daemon/backwards_invocation"
 	"github.com/langgenius/dify-plugin-daemon/internal/core/session_manager"
 	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/requests"
 	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/tool_entities"
@@ -17,8 +18,8 @@ func InvokeTool(
 		session,
 		request,
 		128,
-		PLUGIN_ACCESS_TYPE_TOOL,
-		PLUGIN_ACCESS_ACTION_INVOKE_TOOL,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_TOOL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_INVOKE_TOOL,
 	)
 }
 
@@ -32,7 +33,7 @@ func ValidateToolCredentials(
 		session,
 		request,
 		1,
-		PLUGIN_ACCESS_TYPE_TOOL,
-		PLUGIN_ACCESS_ACTION_VALIDATE_TOOL_CREDENTIALS,
+		backwards_invocation.PLUGIN_ACCESS_TYPE_TOOL,
+		backwards_invocation.PLUGIN_ACCESS_ACTION_VALIDATE_TOOL_CREDENTIALS,
 	)
 }

+ 9 - 1
internal/service/runner.go

@@ -23,8 +23,12 @@ func baseSSEService[T any, R any](
 
 	done := make(chan bool)
 	done_closed := new(int32)
+	closed := new(int32)
 
 	write_data := func(data interface{}) {
+		if atomic.LoadInt32(closed) == 1 {
+			return
+		}
 		writer.Write([]byte("data: "))
 		writer.Write(parser.MarshalJsonBytes(data))
 		writer.Write([]byte("\n\n"))
@@ -59,6 +63,10 @@ func baseSSEService[T any, R any](
 	ticker := time.NewTicker(15 * time.Second)
 	defer ticker.Stop()
 
+	defer func() {
+		atomic.StoreInt32(closed, 1)
+	}()
+
 	for {
 		select {
 		case <-writer.CloseNotify():
@@ -75,6 +83,6 @@ func baseSSEService[T any, R any](
 				return
 			}
 		}
-
 	}
+
 }

+ 2 - 1
internal/types/entities/requests/model.go

@@ -14,11 +14,12 @@ type BaseRequestInvokeModel struct {
 }
 
 type InvokeLLMSchema struct {
+	Mode            string                             `json:"mode" validate:"required"`
 	ModelParameters map[string]any                     `json:"model_parameters"  validate:"omitempty,dive,is_basic_type"`
 	PromptMessages  []model_entities.PromptMessage     `json:"prompt_messages"  validate:"omitempty,dive"`
 	Tools           []model_entities.PromptMessageTool `json:"tools" validate:"omitempty,dive"`
 	Stop            []string                           `json:"stop" validate:"omitempty"`
-	Stream          bool                               `json:"stream" `
+	Stream          bool                               `json:"stream"`
 }
 
 type RequestInvokeLLM struct {

+ 8 - 0
internal/utils/http_requests/http_warpper.go

@@ -4,6 +4,8 @@ import (
 	"bufio"
 	"bytes"
 	"encoding/json"
+	"fmt"
+	"io"
 	"net/http"
 	"time"
 
@@ -73,6 +75,12 @@ func RequestAndParseStream[T any](client *http.Client, url string, method string
 		return nil, err
 	}
 
+	if resp.StatusCode != http.StatusOK {
+		defer resp.Body.Close()
+		error_text, _ := io.ReadAll(resp.Body)
+		return nil, fmt.Errorf("request failed with status code: %d and respond with: %s", resp.StatusCode, error_text)
+	}
+
 	ch := stream.NewStreamResponse[T](1024)
 
 	// get read timeout

+ 3 - 1
internal/utils/parser/struct2map_test.go

@@ -1,6 +1,8 @@
 package parser
 
-import "testing"
+import (
+	"testing"
+)
 
 func TestStruct2Map(t *testing.T) {
 	type Base struct {