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

154 lines
4.8 KiB
Go

package runtimeprep
import (
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
)
const rtkInstructionsMarkdown = `# RTK - Rust Token Killer
RTK is a token-optimized CLI proxy for shell commands.
## Rule
Always prefix supported shell commands with ` + "`rtk`" + `.
Examples:
` + "```bash" + `
rtk git status
rtk go test ./...
rtk pnpm test
rtk pytest -q
` + "```" + `
Use ` + "`rtk proxy <cmd>`" + ` when raw output is required. Use ` + "`rtk gain`" + ` or
` + "`rtk gain --history`" + ` to inspect Session-local token savings.
`
type sessionRTKRuntime struct {
Executable string
Instructions string
Env []string
ExecutableCreated bool
InstructionsCreated bool
}
// prepareSessionRTK copies an already available RTK executable and the
// provider-neutral RTK.md instructions into the exact Session runtime. It
// deliberately does not run a package manager or upstream installer.
func prepareSessionRTK(runtimeRoot string, resolveSource func() (string, error)) (sessionRTKRuntime, error) {
rtkRoot := filepath.Join(runtimeRoot, "rtk")
binDir := filepath.Join(rtkRoot, "bin")
dataDir := filepath.Join(rtkRoot, "data")
teeDir := filepath.Join(rtkRoot, "tee")
for _, dir := range []string{binDir, dataDir, teeDir} {
if err := os.MkdirAll(dir, 0o700); err != nil {
return sessionRTKRuntime{}, fmt.Errorf("create session RTK directory: %w", err)
}
}
target := filepath.Join(binDir, rtkExecutableName())
executableCreated := false
if info, statErr := os.Stat(target); statErr == nil {
if !info.Mode().IsRegular() {
return sessionRTKRuntime{}, fmt.Errorf("session rtk executable is not a regular file: %s", target)
}
// A regular target preserves the launch-time RTK version on resume.
} else if !os.IsNotExist(statErr) {
return sessionRTKRuntime{}, fmt.Errorf("inspect session RTK executable: %w", statErr)
} else {
source, err := resolveSource()
if err != nil {
return sessionRTKRuntime{}, err
}
source = filepath.Clean(strings.TrimSpace(source))
if source == "." || source == "" {
return sessionRTKRuntime{}, errors.New("tutti-managed rtk executable path is empty")
}
source, err = filepath.EvalSymlinks(source)
if err != nil {
return sessionRTKRuntime{}, fmt.Errorf("resolve rtk executable: %w", err)
}
info, err := os.Stat(source)
if err != nil {
return sessionRTKRuntime{}, fmt.Errorf("inspect rtk executable: %w", err)
}
if !info.Mode().IsRegular() {
return sessionRTKRuntime{}, fmt.Errorf("rtk executable is not a regular file: %s", source)
}
if err := copyFile(source, target, 0o700); err != nil {
return sessionRTKRuntime{}, fmt.Errorf("copy RTK into session runtime: %w", err)
}
executableCreated = true
}
instructionsPath := filepath.Join(rtkRoot, "RTK.md")
_, statErr := os.Stat(instructionsPath)
instructionsCreated := os.IsNotExist(statErr)
if statErr != nil && !instructionsCreated {
return sessionRTKRuntime{}, fmt.Errorf("inspect session RTK instructions: %w", statErr)
}
if err := os.WriteFile(instructionsPath, []byte(rtkInstructionsMarkdown), 0o600); err != nil {
return sessionRTKRuntime{}, fmt.Errorf("write session RTK instructions: %w", err)
}
return sessionRTKRuntime{
Executable: target,
Instructions: instructionsPath,
ExecutableCreated: executableCreated,
InstructionsCreated: instructionsCreated,
Env: []string{
"RTK_DB_PATH=" + filepath.Join(dataDir, "usage.db"),
"RTK_TEE_DIR=" + teeDir,
"RTK_TELEMETRY_DISABLED=1",
},
}, nil
}
func rtkExecutableName() string {
if runtime.GOOS == "windows" {
return "rtk.exe"
}
return "rtk"
}
// ensureRTKInstructionsReferenceFirst mirrors RTK's native Codex integration:
// the provider instruction file starts with an absolute @RTK.md reference.
// The complete RTK policy remains inline as a compatibility fallback for
// providers or models that do not resolve instruction-file references.
func ensureRTKInstructionsReferenceFirst(instructionsPath string, input PrepareInput) error {
rtkPath := strings.TrimSpace(input.rtkInstructionsPath)
if !input.RTKSaverMode || rtkPath == "" {
return nil
}
content, err := os.ReadFile(instructionsPath)
if err != nil {
return fmt.Errorf("read provider instructions for RTK reference: %w", err)
}
reference := "@" + rtkPath
newline := "\n"
if strings.Contains(string(content), "\r\n") {
newline = "\r\n"
}
lines := strings.Split(strings.ReplaceAll(string(content), "\r\n", "\n"), "\n")
kept := make([]string, 0, len(lines))
for _, line := range lines {
if strings.TrimSpace(line) != reference {
kept = append(kept, line)
}
}
body := strings.TrimLeft(strings.Join(kept, newline), "\r\n")
next := reference + newline
if body != "" {
next += newline + body
}
if err := os.WriteFile(instructionsPath, []byte(next), 0o644); err != nil {
return fmt.Errorf("write provider RTK instruction reference: %w", err)
}
return nil
}