Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

162 lines
6.9 KiB
Go

package runtime
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
agentruntime "github.com/tutti-os/tutti/packages/agent/daemon/runtime"
market "github.com/tutti-os/tutti/packages/connector/daemon/core"
)
var runtimeIdentityPattern = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._-]{0,190}$`)
// ErrCLIInstallationUnavailable reports that the release-scoped CLI files or
// their verified receipt no longer match the signed installation contract.
// Callers may treat this as explicit installation drift; runtime/profile
// failures remain ordinary errors and must not rewrite durable installation
// truth.
var ErrCLIInstallationUnavailable = errors.New("connector CLI installation is unavailable")
type ManagedRoutePlannerConfig struct {
StateRoot string
UserHome string
Runtimes ConnectorRuntimeResolver
CLIInstallations market.CLIInstallationManager
}
type ManagedRoutePlanner struct {
stateRoot string
userHome string
runtimes ConnectorRuntimeResolver
cliInstallations market.CLIInstallationManager
}
type ManagedRoutePlan struct {
Managed *market.ManagedStdioImplementation
Prepared market.PreparedArtifactReceipt
Resolved ResolvedConnectorRuntime
Executable ConnectorExecutable
InstalledCLI *market.CLIInstallationReceipt
StateDir string
UserHome string
ArtifactTrees []agentruntime.ArtifactTreeIdentity
}
func NewManagedRoutePlanner(config ManagedRoutePlannerConfig) (*ManagedRoutePlanner, error) {
if !filepath.IsAbs(strings.TrimSpace(config.StateRoot)) || !filepath.IsAbs(strings.TrimSpace(config.UserHome)) || config.Runtimes == nil {
return nil, errors.New("connector managed route planner dependencies are invalid")
}
return &ManagedRoutePlanner{stateRoot: filepath.Clean(config.StateRoot), userHome: filepath.Clean(config.UserHome), runtimes: config.Runtimes,
cliInstallations: config.CLIInstallations}, nil
}
// Build verifies the portable managed-runtime contract before a host adapter
// binds protocol-specific MCP/CLI capabilities.
func (planner *ManagedRoutePlanner) Build(ctx context.Context, request market.RuntimeReconcileRequest, prepared market.PreparedArtifactReceipt) (ManagedRoutePlan, error) {
implementation := request.Connector.Release.Manifest.Implementation
if implementation.Kind != market.ImplementationKindManagedStdio || implementation.ManagedStdio == nil {
return ManagedRoutePlan{}, errors.New("only managed_stdio connector implementations are supported")
}
managed := implementation.ManagedStdio
resolved, err := planner.runtimes.ResolveProfile(ctx, managed.Runtime.Profile)
if err != nil {
return ManagedRoutePlan{}, fmt.Errorf("resolve connector managed runtime: %w", err)
}
executable, err := planner.runtimes.VerifyLaunch(managed.Runtime.Profile, managed.Runtime.Language)
if err != nil {
return ManagedRoutePlan{}, fmt.Errorf("verify connector managed runtime launch: %w", err)
}
if err := VerifyRuntimeABI(managed.Runtime, resolved); err != nil {
return ManagedRoutePlan{}, err
}
stateDir, err := SecureConnectorStateDir(planner.stateRoot, request.ConnectionID, request.Connector.Key)
if err != nil {
return ManagedRoutePlan{}, err
}
artifactTrees := []agentruntime.ArtifactTreeIdentity{{Root: prepared.PreparedPath, SHA256: prepared.InventoryDigest}}
var installed *market.CLIInstallationReceipt
if managed.CLI != nil && managed.CLI.Install != nil {
if planner.cliInstallations == nil {
return ManagedRoutePlan{}, errors.New("connector CLI installation resolver is unavailable")
}
receipt, resolveErr := planner.cliInstallations.ResolveCLI(ctx, request.Connector.Release)
if resolveErr != nil {
return ManagedRoutePlan{}, fmt.Errorf("%w: %v", ErrCLIInstallationUnavailable, resolveErr)
}
installed = &receipt
}
return ManagedRoutePlan{Managed: managed, Prepared: prepared, Resolved: resolved, Executable: executable,
InstalledCLI: installed, StateDir: stateDir, UserHome: planner.userHome, ArtifactTrees: artifactTrees}, nil
}
func SecureConnectorStateDir(root, connectionID, connectorKey string) (string, error) {
if !runtimeIdentityPattern.MatchString(connectionID) || !runtimeIdentityPattern.MatchString(connectorKey) {
return "", errors.New("connector state identity is invalid")
}
if err := os.MkdirAll(root, 0o700); err != nil {
return "", err
}
rootReal, err := filepath.EvalSymlinks(root)
if err != nil {
return "", err
}
target := filepath.Join(rootReal, connectionID, connectorKey)
relative, err := filepath.Rel(rootReal, target)
if err != nil || relative == "." || relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
return "", errors.New("connector state directory escapes state root")
}
if err := os.MkdirAll(target, 0o700); err != nil {
return "", err
}
targetReal, err := filepath.EvalSymlinks(target)
if err != nil || (targetReal != rootReal && !strings.HasPrefix(targetReal, rootReal+string(filepath.Separator))) {
return "", errors.New("connector state directory escapes state root")
}
return targetReal, nil
}
func ContainsPermissionScope(values []string, expected string) bool {
for _, value := range values {
if value == expected || strings.HasPrefix(value, expected+":") {
return true
}
}
return false
}
func PreparedEntrypoint(root, relative string) (string, error) {
if !filepath.IsAbs(root) || filepath.IsAbs(relative) || strings.TrimSpace(relative) == "" {
return "", errors.New("connector entrypoint is invalid")
}
root = filepath.Clean(root)
clean := filepath.Clean(filepath.FromSlash(relative))
if clean == "." || clean == ".." || strings.HasPrefix(clean, ".."+string(filepath.Separator)) {
return "", errors.New("connector entrypoint escapes prepared artifact")
}
entrypoint := filepath.Join(root, clean)
if entrypoint != root && !strings.HasPrefix(entrypoint, root+string(filepath.Separator)) {
return "", errors.New("connector entrypoint escapes prepared artifact")
}
info, err := os.Lstat(entrypoint)
if err != nil || !info.Mode().IsRegular() {
return "", errors.New("connector entrypoint is not a regular file")
}
return entrypoint, nil
}
func ConnectorProcessSpec(connectionID, connectorKey, language string, executable ConnectorExecutable, cwd string, args []string,
stateDir, userHome string, artifactTrees []agentruntime.ArtifactTreeIdentity) agentruntime.ProcessSpec {
command := append([]string{executable.Path}, args...)
return agentruntime.ProcessSpec{Provider: "connector:" + connectorKey, RoomID: connectionID, CWD: cwd, Command: command,
Env: []string{"TUTTI_CONNECTOR_CONNECTION_ID=" + connectionID, "TUTTI_CONNECTOR_KEY=" + connectorKey,
"TUTTI_CONNECTOR_LANGUAGE=" + language, "TUTTI_CONNECTOR_STATE_DIR=" + stateDir,
"HOME=" + userHome, "USERPROFILE=" + userHome},
ExecutableIdentity: &agentruntime.ExecutableIdentity{SHA256: executable.SHA256, SizeBytes: executable.SizeBytes},
ArtifactTrees: append([]agentruntime.ArtifactTreeIdentity(nil), artifactTrees...)}
}