MCPcopy Index your code
hub / github.com/coder/coder / executeProposePlanTool

Function executeProposePlanTool

coderd/x/chatd/chattool/proposeplan.go:69–127  ·  view source on GitHub ↗
(
	ctx context.Context,
	conn workspacesdk.AgentConn,
	args ProposePlanArgs,
	resolvePlanPath func(context.Context) (chatPath string, home string, err error),
	storeFile StoreFileFunc,
)

Source from the content-addressed store, hash-verified

67}
68
69func executeProposePlanTool(
70 ctx context.Context,
71 conn workspacesdk.AgentConn,
72 args ProposePlanArgs,
73 resolvePlanPath func(context.Context) (chatPath string, home string, err error),
74 storeFile StoreFileFunc,
75) (fantasy.ToolResponse, error) {
76 requestedPath := strings.TrimSpace(args.Path)
77 if requestedPath == "" {
78 return fantasy.NewTextErrorResponse("path is required (use the chat-specific absolute plan path)"), nil
79 }
80 if !strings.HasSuffix(requestedPath, ".md") {
81 return fantasy.NewTextErrorResponse("path must end with .md"), nil
82 }
83
84 hasPlanFileName := looksLikePlanFileName(requestedPath)
85 if hasPlanFileName && !isAbsolutePath(requestedPath) {
86 return fantasy.NewTextErrorResponse(
87 "plan files must use absolute paths; use the chat-specific absolute plan path",
88 ), nil
89 }
90
91 if resolvePlanPath != nil && hasPlanFileName {
92 chatPath, home, err := resolvePlanPath(ctx)
93 if resp, rejected := rejectSharedPlanPath(requestedPath, home, chatPath, err); rejected {
94 return resp, nil
95 }
96 }
97
98 rc, _, err := conn.ReadFile(ctx, requestedPath, 0, maxProposePlanSize+1)
99 if err != nil {
100 return fantasy.NewTextErrorResponse(err.Error()), nil
101 }
102 defer rc.Close()
103
104 data, err := io.ReadAll(rc)
105 if err != nil {
106 return fantasy.NewTextErrorResponse(err.Error()), nil
107 }
108 if len(data) == 0 || strings.TrimSpace(string(data)) == "" {
109 return fantasy.NewTextErrorResponse("plan file is empty; write your plan to " + requestedPath + " before proposing"), nil
110 }
111 if int64(len(data)) > maxProposePlanSize {
112 return fantasy.NewTextErrorResponse("plan file exceeds 32 KiB size limit"), nil
113 }
114
115 attachment, err := storeFile(ctx, filepath.Base(requestedPath), requestedPath, data)
116 if err != nil {
117 return fantasy.NewTextErrorResponse("failed to store plan file: " + err.Error()), nil
118 }
119
120 return WithAttachments(toolResponse(map[string]any{
121 "ok": true,
122 "path": requestedPath,
123 "kind": "plan",
124 "file_id": attachment.FileID.String(),
125 "media_type": attachment.MediaType,
126 }), attachment), nil

Callers 1

ProposePlanFunction · 0.85

Calls 10

looksLikePlanFileNameFunction · 0.85
isAbsolutePathFunction · 0.85
rejectSharedPlanPathFunction · 0.85
WithAttachmentsFunction · 0.85
toolResponseFunction · 0.85
ReadFileMethod · 0.65
CloseMethod · 0.65
ErrorMethod · 0.45
ReadAllMethod · 0.45
StringMethod · 0.45

Tested by

no test coverage detected