@@ -82,30 +82,60 @@ export const api = {
8282
8383
8484 // AI wizard – talks to /agent/wizard on the backend
85+ // askYamlWizard: async (input: {
86+ // repoUrl: string;
87+ // provider: string;
88+ // branch: string;
89+ // message?: string;
90+ // yaml?: string;
91+ // }) => {
92+ // const res = await fetch(`${SERVER_BASE}/agent/wizard/ai`, {
93+ // method: "POST",
94+ // headers: { "Content-Type": "application/json" },
95+ // credentials: "include",
96+ // body: JSON.stringify(input),
97+ // });
98+
99+ // const payload = await res.json().catch(() => ({}));
100+ // if (!res.ok || (payload as any)?.success === false) {
101+ // throw new Error(
102+ // (payload as any)?.error || res.statusText || "Agent error"
103+ // );
104+ // }
105+
106+ // // whatever runWizardAgent returns is in payload.data
107+ // return (payload as any).data;
108+ // },
109+
85110 askYamlWizard : async ( input : {
86- repoUrl : string ;
87- provider : string ;
88- branch : string ;
89- message ?: string ;
90- yaml ?: string ;
91- } ) => {
92- const res = await fetch ( `${ SERVER_BASE } /agent/wizard` , {
93- method : "POST" ,
94- headers : { "Content-Type" : "application/json" } ,
95- credentials : "include" ,
96- body : JSON . stringify ( input ) ,
97- } ) ;
111+ repoUrl : string ;
112+ provider : string ;
113+ branch : string ;
114+ message ?: string ; // frontend name
115+ yaml ?: string ;
116+ } ) => {
117+ const payload = {
118+ ...input ,
119+ prompt : input . message ?? "" , // 👈 REQUIRED BY BACKEND
120+ } ;
121+
122+ delete ( payload as any ) . message ; // 👈 prevent backend confusion
123+
124+ const res = await fetch ( `${ SERVER_BASE } /agent/wizard/ai` , {
125+ method : "POST" ,
126+ headers : { "Content-Type" : "application/json" } ,
127+ credentials : "include" ,
128+ body : JSON . stringify ( payload ) ,
129+ } ) ;
98130
99- const payload = await res . json ( ) . catch ( ( ) => ( { } ) ) ;
100- if ( ! res . ok || ( payload as any ) ?. success === false ) {
101- throw new Error (
102- ( payload as any ) ?. error || res . statusText || "Agent error"
103- ) ;
104- }
131+ const data = await res . json ( ) . catch ( ( ) => ( { } ) ) ;
105132
106- // whatever runWizardAgent returns is in payload.data
107- return ( payload as any ) . data ;
108- } ,
133+ if ( ! res . ok || data ?. success === false ) {
134+ throw new Error ( data ?. error || res . statusText || "Agent error" ) ;
135+ }
136+
137+ return data . data ;
138+ } ,
109139
110140 // ===== MCP helpers for repos / branches / pipeline generation =====
111141 async listRepos ( ) : Promise < { repos : string [ ] } > {
@@ -151,75 +181,6 @@ export const api = {
151181 return { branches : cachedBranches . get ( repo ) ?? [ ] } ;
152182 }
153183 } ,
154- // async listRepos(): Promise<{ repos: string[] }> {
155- // // If we already have repos cached, reuse them.
156- // if (cachedRepos && cachedRepos.length > 0) {
157- // return { repos: cachedRepos };
158- // }
159-
160- // // If we've already tried once and failed, don't hammer the server.
161- // if (reposAttempted && !cachedRepos) {
162- // return { repos: [] };
163- // }
164-
165- // reposAttempted = true;
166-
167- // try {
168- // const outer = await mcp<{
169- // provider: string;
170- // user: string;
171- // repositories: { full_name: string }[];
172- // }>("repo_reader", {});
173-
174- // const repos = outer?.repositories?.map((r) => r.full_name) ?? [];
175- // cachedRepos = repos;
176- // return { repos };
177- // } catch (err) {
178- // console.error("[api.listRepos] failed:", err);
179- // // Don't throw to avoid retry loops from effects; just return whatever we have (or empty).
180- // return { repos: cachedRepos ?? [] };
181- // }
182- // },
183-
184- async listBranches ( repo : string ) : Promise < { branches : string [ ] } > {
185- // ✅ If we already have branches cached for this repo, reuse them.
186- const cached = cachedBranches . get ( repo ) ;
187- if ( cached ) {
188- return { branches : cached } ;
189- }
190-
191- try {
192- // For now we still use repo_reader, but we only call it
193- // when the cache is cold. We can later swap this to a
194- // more specific MCP tool like "repo_branches".
195- const outer = await mcp < {
196- success ?: boolean ;
197- data ?: { repositories : { full_name : string ; branches ?: string [ ] } [ ] } ;
198- repositories ?: { full_name : string ; branches ?: string [ ] } [ ] ;
199- } > ( "repo_reader" , {
200- // This extra input is safe: current server ignores it,
201- // future server can use it to optimize.
202- repoFullName : repo ,
203- } ) ;
204-
205- // Unwrap the payload (tool responses come back as { success, data })
206- const body = ( outer as any ) ?. data ?? outer ;
207-
208- const match = body ?. repositories ?. find ( ( r : any ) => r . full_name === repo ) ;
209- const branches = match ?. branches ?? [ ] ;
210-
211- // Cache even empty arrays so we don't re-query a repo with no branches
212- cachedBranches . set ( repo , branches ) ;
213-
214- return { branches } ;
215- } catch ( err ) {
216- console . error ( "[api.listBranches] failed:" , err ) ;
217-
218- // If we have anything cached (even empty), use it.
219- const fallback = cachedBranches . get ( repo ) ?? [ ] ;
220- return { branches : fallback } ;
221- }
222- } ,
223184
224185 async createPipeline ( payload : any ) {
225186 const { repo, branch, template = "node_app" , options } = payload || { } ;
0 commit comments