๐Ÿ“ฆ langgenius / dify-plugin-daemon

๐Ÿ“„ environment_python.go ยท 92 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92package local_runtime

import (
	_ "embed"
	"fmt"

	"github.com/langgenius/dify-plugin-daemon/pkg/utils/log"
)

func (p *LocalPluginRuntime) InitPythonEnvironment() error {
	// prepare uv environment
	uvPath, err := p.prepareUV()
	if err != nil {
		return fmt.Errorf("failed to find uv path: %w", err)
	}

	// check if virtual environment exists
	venv, err := p.checkPythonVirtualEnvironment()
	switch err {
	case ErrVirtualEnvironmentInvalid:
		// remove the venv and rebuild it
		p.deleteVirtualEnvironment()

		// create virtual environment
		venv, err = p.createVirtualEnvironment(uvPath)
		if err != nil {
			return fmt.Errorf("failed to create virtual environment: %w", err)
		}
	case ErrVirtualEnvironmentNotFound:
		// create virtual environment
		venv, err = p.createVirtualEnvironment(uvPath)
		if err != nil {
			return fmt.Errorf("failed to create virtual environment: %w", err)
		}
	case nil:
		// PATCH:
		//  plugin sdk version less than 0.0.1b70 contains a memory leak bug
		//  to reach a better user experience, we will patch it here using a patched file
		// https://github.com/langgenius/dify-plugin-sdks/commit/161045b65f708d8ef0837da24440ab3872821b3b
		dependencyFilePath, err := p.getDependencyFilePath()
		if err != nil {
			log.Error("failed to get dependency file path for patching", "error", err)
		} else if err := p.patchPluginSdk(
			dependencyFilePath,
			venv.pythonInterpreterPath,
		); err != nil {
			log.Error("failed to patch the plugin sdk", "error", err)
		}

		// everything is good, return nil
		return nil
	default:
		return fmt.Errorf("failed to check virtual environment: %w", err)
	}

	// detect dependency file type and install dependencies
	dependencyFileType, err := p.detectDependencyFileType()
	if err != nil {
		return fmt.Errorf("failed to detect dependency file: %w", err)
	}

	if err := p.installDependencies(uvPath, dependencyFileType); err != nil {
		return fmt.Errorf("failed to install dependencies: %w", err)
	}

	// pre-compile the plugin to avoid costly compilation on first invocation
	if err := p.preCompile(venv.pythonInterpreterPath); err != nil {
		return fmt.Errorf("failed to pre-compile the plugin: %w", err)
	}

	// PATCH:
	//  plugin sdk version less than 0.0.1b70 contains a memory leak bug
	//  to reach a better user experience, we will patch it here using a patched file
	// https://github.com/langgenius/dify-plugin-sdks/commit/161045b65f708d8ef0837da24440ab3872821b3b
	dependencyFilePath, err := p.getDependencyFilePath()
	if err != nil {
		log.Error("failed to get dependency file path for patching", "error", err)
	} else if err := p.patchPluginSdk(
		dependencyFilePath,
		venv.pythonInterpreterPath,
	); err != nil {
		log.Error("failed to patch the plugin sdk", "error", err)
	}

	// mark the virtual environment as valid if everything goes well
	if err := p.markVirtualEnvironmentAsValid(); err != nil {
		log.Error("failed to mark the virtual environment as valid", "error", err)
	}

	return nil
}