Files
WeKnora/pluginsdk/pluginapi/handshake.go
T
lyingbug 4328ab26a9 feat(plugin): code plugins — extension protocol, Go SDK, plugin host, web search and data source adapters (#3720)
* feat(pluginsdk): extension protocol v1, Go SDK and conformance suite
* feat(plugin): run code plugins in an embedded plugin host
* feat(plugin): remote adapters for web search and data sources
* fix(plugin): show plugin errors by their message
* feat(frontend): plugin connectors and web search providers in the UI
* docs(pluginsdk): how to write, package, test and install a plugin
* fix(plugin): gofmt two files and read openapi.yaml line-ending agnostic
* fix(plugin): mark a host plugin ready before Activate returns
2026-09-26 14:45:15 +08:00

64 lines
2.1 KiB
Go

package pluginapi
import (
"fmt"
"strings"
)
// Environment a host plugin is started with.
const (
// EnvSocket is where the plugin must listen (a unix socket path, or a
// host:port when EnvNetwork is "tcp").
EnvSocket = "WEKNORA_PLUGIN_SOCKET"
// EnvNetwork is "unix" (default) or "tcp".
EnvNetwork = "WEKNORA_PLUGIN_NETWORK"
// EnvToken is the bearer token every call from the host carries.
EnvToken = "WEKNORA_PLUGIN_TOKEN"
// EnvPluginID and EnvPluginVersion name the package being run.
EnvPluginID = "WEKNORA_PLUGIN_ID"
EnvPluginVersion = "WEKNORA_PLUGIN_VERSION"
// EnvAddr and EnvSecret configure a remote plugin (not started by a
// host): where to listen and the shared secret calls are signed with.
EnvAddr = "WEKNORA_PLUGIN_ADDR"
EnvSecret = "WEKNORA_PLUGIN_SECRET"
)
// handshakePrefix starts the line a host plugin prints on stdout once it is
// ready: WEKNORA_PLUGIN|1|unix|/path/to.sock
const handshakePrefix = "WEKNORA_PLUGIN"
// Handshake is the readiness line of a host plugin.
type Handshake struct {
Protocol string
Network string // unix | tcp
Address string
}
// String renders the handshake line (without a newline).
func (h Handshake) String() string {
return strings.Join([]string{handshakePrefix, h.Protocol, h.Network, h.Address}, "|")
}
// ParseHandshake reads a handshake line. ok is false for any other line,
// which the host treats as log output.
func ParseHandshake(line string) (h Handshake, ok bool, err error) {
parts := strings.Split(strings.TrimSpace(line), "|")
if len(parts) == 0 || parts[0] != handshakePrefix {
return Handshake{}, false, nil
}
if len(parts) != 4 {
return Handshake{}, true, fmt.Errorf("malformed handshake %q", line)
}
h = Handshake{Protocol: parts[1], Network: parts[2], Address: parts[3]}
if h.Protocol != ProtocolVersion {
return h, true, fmt.Errorf("plugin speaks protocol %s, host speaks %s", h.Protocol, ProtocolVersion)
}
if h.Network != "unix" && h.Network != "tcp" {
return h, true, fmt.Errorf("unknown handshake network %q", h.Network)
}
if h.Address == "" {
return h, true, fmt.Errorf("handshake has no address")
}
return h, true, nil
}