Procházet zdrojové kódy

feat: add command line support to agent

Yeuoly před 6 měsíci
rodič
revize
0f94beb9ff

+ 56 - 2
cmd/commandline/plugin/module.go

@@ -35,6 +35,22 @@ Parameters:
 {{- end}}
 `
 
+const AGENT_MODULE_TEMPLATE = `
+========== {{.Identity.Name}} ==========
+Author: {{.Identity.Author}}
+Label: {{.Identity.Label.EnUS}}
+Description: {{.Description.EnUS}}
+Parameters:
+{{- range .Parameters}}
+  - Name: {{.Name}}
+    Type: {{.Type}}
+    Required: {{.Required}}
+    {{- if .Default}}
+    Default: {{.Default}}
+    {{- end}}
+{{- end}}
+`
+
 const MODEL_MODULE_TEMPLATE = `
 ========== {{.Model}} ==========
 Name: {{.Model}}
@@ -109,13 +125,35 @@ Permissions:
 `
 
 func ModuleList(pluginPath string) {
-	decoder, err := decoder.NewFSPluginDecoder(pluginPath)
+	var pluginDecoder decoder.PluginDecoder
+	var err error
+
+	stat, err := os.Stat(pluginPath)
+	if err != nil {
+		log.Error("failed to get plugin file stat: %s", err)
+		return
+	}
+
+	if stat.IsDir() {
+		pluginDecoder, err = decoder.NewFSPluginDecoder(pluginPath)
+	} else {
+		fileContent, err := os.ReadFile(pluginPath)
+		if err != nil {
+			log.Error("failed to read plugin file: %s", err)
+			return
+		}
+		pluginDecoder, err = decoder.NewZipPluginDecoder(fileContent)
+		if err != nil {
+			log.Error("failed to create zip plugin decoder: %s", err)
+			return
+		}
+	}
 	if err != nil {
 		log.Error("your plugin is not a valid plugin: %s", err)
 		return
 	}
 
-	manifest, err := decoder.Manifest()
+	manifest, err := pluginDecoder.Manifest()
 	if err != nil {
 		log.Error("failed to get manifest: %s", err)
 		return
@@ -137,6 +175,22 @@ func ModuleList(pluginPath string) {
 		}
 	}
 
+	if manifest.AgentStrategy != nil {
+		for _, strategy := range manifest.AgentStrategy.Strategies {
+			tmpl, err := template.New("agent").Parse(AGENT_MODULE_TEMPLATE)
+			if err != nil {
+				log.Error("failed to parse template: %s", err)
+				return
+			}
+
+			err = tmpl.Execute(os.Stdout, strategy)
+			if err != nil {
+				log.Error("failed to execute template: %s", err)
+				return
+			}
+		}
+	}
+
 	if manifest.Model != nil {
 		for _, model := range manifest.Model.Models {
 			tmpl, err := template.New("model").Parse(MODEL_MODULE_TEMPLATE)

+ 29 - 0
internal/core/plugin_packager/decoder/helper.go

@@ -240,6 +240,35 @@ func (p *PluginDecoderHelper) Manifest(decoder PluginDecoder) (plugin_entities.P
 		dec.Model = &pluginDec
 	}
 
+	for _, agentStrategy := range plugins.AgentStrategies {
+		// read yaml
+		pluginYaml, err := decoder.ReadFile(agentStrategy)
+		if err != nil {
+			return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to read agent strategy file: %s", agentStrategy))
+		}
+
+		pluginDec, err := parser.UnmarshalYamlBytes[plugin_entities.AgentStrategyProviderDeclaration](pluginYaml)
+		if err != nil {
+			return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to unmarshal plugin file: %s", agentStrategy))
+		}
+
+		for _, strategyFile := range pluginDec.StrategyFiles {
+			strategyFileContent, err := decoder.ReadFile(strategyFile)
+			if err != nil {
+				return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to read agent strategy file: %s", strategyFile))
+			}
+
+			strategyDec, err := parser.UnmarshalYamlBytes[plugin_entities.AgentStrategyDeclaration](strategyFileContent)
+			if err != nil {
+				return plugin_entities.PluginDeclaration{}, errors.Join(err, fmt.Errorf("failed to unmarshal agent strategy file: %s", strategyFile))
+			}
+
+			pluginDec.Strategies = append(pluginDec.Strategies, strategyDec)
+		}
+
+		dec.AgentStrategy = &pluginDec
+	}
+
 	dec.FillInDefaultValues()
 
 	// verify signature

+ 3 - 1
pkg/entities/manifest_entities/tags.go

@@ -23,6 +23,7 @@ const (
 	PLUGIN_TAG_BUSINESS      PluginTag = "business"
 	PLUGIN_TAG_ENTERTAINMENT PluginTag = "entertainment"
 	PLUGIN_TAG_UTILITIES     PluginTag = "utilities"
+	PLUGIN_TAG_AGENT         PluginTag = "agent"
 	PLUGIN_TAG_OTHER         PluginTag = "other"
 )
 
@@ -44,7 +45,8 @@ func isPluginTag(fl validator.FieldLevel) bool {
 		string(PLUGIN_TAG_BUSINESS),
 		string(PLUGIN_TAG_ENTERTAINMENT),
 		string(PLUGIN_TAG_UTILITIES),
-		string(PLUGIN_TAG_OTHER):
+		string(PLUGIN_TAG_OTHER),
+		string(PLUGIN_TAG_AGENT):
 		return true
 	}
 	return false

+ 1 - 1
pkg/entities/plugin_entities/plugin_declaration.go

@@ -248,7 +248,7 @@ func (p *PluginDeclaration) Identity() string {
 
 func (p *PluginDeclaration) ManifestValidate() error {
 	if p.Endpoint == nil && p.Model == nil && p.Tool == nil && p.AgentStrategy == nil {
-		return fmt.Errorf("at least one of endpoint, model, or tool must be provided")
+		return fmt.Errorf("at least one of endpoint, model, tool, or agent_strategy must be provided")
 	}
 
 	if p.Model != nil && p.Tool != nil {