返回 DeepSeek-Reasonix
prompts.go
根目录 / internal / plugin / prompts.go
1 package plugin
2
3 import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "strings"
8 )
9
10 // Prompt is an MCP prompt exposed by a server. It surfaces in the chat TUI as a
11 // slash command "/mcp__<server>__<prompt>"; running it fetches the rendered
12 // prompt and sends it to the model as a turn.
13 type Prompt struct {
14 Name string // "mcp__<server>__<prompt>" — the slash-command body
15 Server string // owning server name
16 Raw string // original prompt name for prompts/get
17 Description string // human-readable summary
18 Args []PromptArg // declared arguments, in order
19 client *Client
20 }
21
22 // PromptArg is one declared prompt argument. Reasonix maps space-separated
23 // positional command arguments onto these in order, matching Claude Code.
24 type PromptArg struct {
25 Name string `json:"name"`
26 Description string `json:"description"`
27 Required bool `json:"required"`
28 }
29
30 // Get fetches the prompt with the given arguments and flattens its returned
31 // messages into a single text block to send to the model.
32 func (p Prompt) Get(ctx context.Context, args map[string]string) (string, error) {
33 return p.client.getPrompt(ctx, p.Raw, args)
34 }
35
36 func (c *Client) listPrompts(ctx context.Context) ([]Prompt, error) {
37 res, err := c.call(ctx, "prompts/list", map[string]any{})
38 if err != nil {
39 return nil, err
40 }
41 var out struct {
42 Prompts []struct {
43 Name string `json:"name"`
44 Description string `json:"description"`
45 Arguments []PromptArg `json:"arguments"`
46 } `json:"prompts"`
47 }
48 if err := json.Unmarshal(res, &out); err != nil {
49 return nil, fmt.Errorf("plugin %q: decode prompts/list: %w", c.name, err)
50 }
51 prompts := make([]Prompt, 0, len(out.Prompts))
52 for _, p := range out.Prompts {
53 prompts = append(prompts, Prompt{
54 Name: "mcp__" + normalizeName(c.name) + "__" + normalizeName(p.Name),
55 Server: c.name,
56 Raw: p.Name,
57 Description: p.Description,
58 Args: p.Arguments,
59 client: c,
60 })
61 }
62 return prompts, nil
63 }
64
65 func (c *Client) getPrompt(ctx context.Context, name string, args map[string]string) (string, error) {
66 params := map[string]any{"name": name}
67 if len(args) > 0 {
68 params["arguments"] = args
69 }
70 res, err := c.call(ctx, "prompts/get", params)
71 if err != nil {
72 return "", err
73 }
74 var out struct {
75 Messages []struct {
76 Role string `json:"role"`
77 Content struct {
78 Type string `json:"type"`
79 Text string `json:"text"`
80 } `json:"content"`
81 } `json:"messages"`
82 }
83 if err := json.Unmarshal(res, &out); err != nil {
84 return "", fmt.Errorf("plugin %q: decode prompts/get: %w", c.name, err)
85 }
86 var sb strings.Builder
87 for _, m := range out.Messages {
88 if m.Content.Type == "text" && m.Content.Text != "" {
89 if sb.Len() > 0 {
90 sb.WriteString("\n\n")
91 }
92 sb.WriteString(m.Content.Text)
93 }
94 }
95 return sb.String(), nil
96 }
97
97 lines GO