返回 DeepSeek-Reasonix
render.go
根目录 / internal / instruction / render.go
1 package instruction
2
3 import (
4 "fmt"
5 "path/filepath"
6 "strings"
7 )
8
9 // Block renders resolved standing instructions in broad-to-specific order.
10 // Diagnostics stay host-side; malformed imports are already annotated at the
11 // exact source line and must not become additional model instructions.
12 func Block(documents []Document) string {
13 if len(documents) == 0 {
14 return ""
15 }
16 var b strings.Builder
17 b.WriteString("# Instructions\n\n")
18 b.WriteString("Standing guidance resolved for this workspace and target path. Later entries are more specific and take precedence when rules conflict; the current user request still has highest priority.\n")
19 workspaceRoot := providerWorkspaceRoot(documents)
20 for _, doc := range documents {
21 fmt.Fprintf(&b, "\n## %s (%s", providerDocumentPath(doc, workspaceRoot), doc.Scope)
22 if doc.Scope != ScopeUser && strings.TrimSpace(doc.Directory) != "" {
23 fmt.Fprintf(&b, ", applies to %s", providerDirectoryPath(doc.Directory, workspaceRoot))
24 }
25 b.WriteString(")\n\n")
26 b.WriteString(strings.TrimSpace(doc.Body))
27 b.WriteByte('\n')
28 }
29 return strings.TrimSpace(b.String())
30 }
31
32 func providerWorkspaceRoot(documents []Document) string {
33 for _, doc := range documents {
34 if doc.Scope == ScopeUser || doc.Depth < 0 || strings.TrimSpace(doc.Directory) == "" {
35 continue
36 }
37 root := absolutePath(doc.Directory)
38 for range doc.Depth {
39 root = filepath.Dir(root)
40 }
41 return root
42 }
43 return ""
44 }
45
46 func providerDocumentPath(doc Document, workspaceRoot string) string {
47 if doc.Scope == ScopeUser {
48 return filepath.ToSlash(filepath.Join("user", filepath.Base(doc.Path)))
49 }
50 if workspaceRoot != "" {
51 if rel, err := filepath.Rel(workspaceRoot, absolutePath(doc.Path)); err == nil && filepath.IsLocal(rel) {
52 return filepath.ToSlash(filepath.Join("workspace", rel))
53 }
54 }
55 label := string(doc.Scope)
56 if label == "" {
57 label = "workspace"
58 }
59 return filepath.ToSlash(filepath.Join(label, filepath.Base(doc.Path)))
60 }
61
62 func providerDirectoryPath(dir, workspaceRoot string) string {
63 if workspaceRoot != "" {
64 if rel, err := filepath.Rel(workspaceRoot, absolutePath(dir)); err == nil && filepath.IsLocal(rel) {
65 if rel == "." {
66 return "workspace"
67 }
68 return filepath.ToSlash(filepath.Join("workspace", rel))
69 }
70 }
71 return "workspace"
72 }
73
74 func Compose(base string, documents []Document) string {
75 block := Block(documents)
76 if block == "" {
77 return base
78 }
79 if strings.TrimSpace(base) == "" {
80 return block
81 }
82 return strings.TrimRight(base, "\n") + "\n\n" + block
83 }
84
84 lines GO