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
}