Sujal Shah commited on
Commit
4ac0af4
·
1 Parent(s): 88700c2

fix: enhance prompt "Invalid or missing provider" bad request error

Browse files
app/lib/hooks/usePromptEnhancer.ts CHANGED
@@ -1,4 +1,5 @@
1
  import { useState } from 'react';
 
2
  import { createScopedLogger } from '~/utils/logger';
3
 
4
  const logger = createScopedLogger('usePromptEnhancement');
@@ -13,54 +14,54 @@ export function usePromptEnhancer() {
13
  };
14
 
15
  const enhancePrompt = async (
16
- input: string,
17
  setInput: (value: string) => void,
18
  model: string,
19
- provider: string,
20
- apiKeys?: Record<string, string>
21
  ) => {
22
  setEnhancingPrompt(true);
23
  setPromptEnhanced(false);
24
-
25
  const requestBody: any = {
26
  message: input,
27
  model,
28
  provider,
29
  };
30
-
31
  if (apiKeys) {
32
  requestBody.apiKeys = apiKeys;
33
  }
34
-
35
  const response = await fetch('/api/enhancer', {
36
  method: 'POST',
37
  body: JSON.stringify(requestBody),
38
  });
39
-
40
  const reader = response.body?.getReader();
41
-
42
  const originalInput = input;
43
-
44
  if (reader) {
45
  const decoder = new TextDecoder();
46
-
47
  let _input = '';
48
  let _error;
49
-
50
  try {
51
  setInput('');
52
-
53
  while (true) {
54
  const { value, done } = await reader.read();
55
-
56
  if (done) {
57
  break;
58
  }
59
-
60
  _input += decoder.decode(value);
61
-
62
  logger.trace('Set input', _input);
63
-
64
  setInput(_input);
65
  }
66
  } catch (error) {
@@ -70,10 +71,10 @@ export function usePromptEnhancer() {
70
  if (_error) {
71
  logger.error(_error);
72
  }
73
-
74
  setEnhancingPrompt(false);
75
  setPromptEnhanced(true);
76
-
77
  setTimeout(() => {
78
  setInput(_input);
79
  });
 
1
  import { useState } from 'react';
2
+ import type { ProviderInfo } from '~/types/model';
3
  import { createScopedLogger } from '~/utils/logger';
4
 
5
  const logger = createScopedLogger('usePromptEnhancement');
 
14
  };
15
 
16
  const enhancePrompt = async (
17
+ input: string,
18
  setInput: (value: string) => void,
19
  model: string,
20
+ provider: ProviderInfo,
21
+ apiKeys?: Record<string, string>,
22
  ) => {
23
  setEnhancingPrompt(true);
24
  setPromptEnhanced(false);
25
+
26
  const requestBody: any = {
27
  message: input,
28
  model,
29
  provider,
30
  };
31
+
32
  if (apiKeys) {
33
  requestBody.apiKeys = apiKeys;
34
  }
35
+
36
  const response = await fetch('/api/enhancer', {
37
  method: 'POST',
38
  body: JSON.stringify(requestBody),
39
  });
40
+
41
  const reader = response.body?.getReader();
42
+
43
  const originalInput = input;
44
+
45
  if (reader) {
46
  const decoder = new TextDecoder();
47
+
48
  let _input = '';
49
  let _error;
50
+
51
  try {
52
  setInput('');
53
+
54
  while (true) {
55
  const { value, done } = await reader.read();
56
+
57
  if (done) {
58
  break;
59
  }
60
+
61
  _input += decoder.decode(value);
62
+
63
  logger.trace('Set input', _input);
64
+
65
  setInput(_input);
66
  }
67
  } catch (error) {
 
71
  if (_error) {
72
  logger.error(_error);
73
  }
74
+
75
  setEnhancingPrompt(false);
76
  setPromptEnhanced(true);
77
+
78
  setTimeout(() => {
79
  setInput(_input);
80
  });
app/routes/api.enhancer.ts CHANGED
@@ -2,7 +2,7 @@ import { type ActionFunctionArgs } from '@remix-run/cloudflare';
2
  import { StreamingTextResponse, parseStreamPart } from 'ai';
3
  import { streamText } from '~/lib/.server/llm/stream-text';
4
  import { stripIndents } from '~/utils/stripIndent';
5
- import type { StreamingOptions } from '~/lib/.server/llm/stream-text';
6
 
7
  const encoder = new TextEncoder();
8
  const decoder = new TextDecoder();
@@ -12,25 +12,27 @@ export async function action(args: ActionFunctionArgs) {
12
  }
13
 
14
  async function enhancerAction({ context, request }: ActionFunctionArgs) {
15
- const { message, model, provider, apiKeys } = await request.json<{
16
  message: string;
17
  model: string;
18
- provider: string;
19
  apiKeys?: Record<string, string>;
20
  }>();
21
 
22
- // Validate 'model' and 'provider' fields
 
 
23
  if (!model || typeof model !== 'string') {
24
  throw new Response('Invalid or missing model', {
25
  status: 400,
26
- statusText: 'Bad Request'
27
  });
28
  }
29
 
30
- if (!provider || typeof provider !== 'string') {
31
  throw new Response('Invalid or missing provider', {
32
  status: 400,
33
- statusText: 'Bad Request'
34
  });
35
  }
36
 
@@ -39,7 +41,9 @@ async function enhancerAction({ context, request }: ActionFunctionArgs) {
39
  [
40
  {
41
  role: 'user',
42
- content: `[Model: ${model}]\n\n[Provider: ${provider}]\n\n` + stripIndents`
 
 
43
  I want you to improve the user prompt that is wrapped in \`<original_prompt>\` tags.
44
 
45
  IMPORTANT: Only respond with the improved prompt and nothing else!
@@ -52,23 +56,24 @@ async function enhancerAction({ context, request }: ActionFunctionArgs) {
52
  ],
53
  context.cloudflare.env,
54
  undefined,
55
- apiKeys
56
  );
57
 
58
  const transformStream = new TransformStream({
59
  transform(chunk, controller) {
60
  const text = decoder.decode(chunk);
61
- const lines = text.split('\n').filter(line => line.trim() !== '');
62
-
63
  for (const line of lines) {
64
  try {
65
  const parsed = parseStreamPart(line);
 
66
  if (parsed.type === 'text') {
67
  controller.enqueue(encoder.encode(parsed.value));
68
  }
69
  } catch (e) {
70
- // Skip invalid JSON lines
71
- console.warn('Failed to parse stream part:', line);
72
  }
73
  }
74
  },
@@ -83,7 +88,7 @@ async function enhancerAction({ context, request }: ActionFunctionArgs) {
83
  if (error instanceof Error && error.message?.includes('API key')) {
84
  throw new Response('Invalid or missing API key', {
85
  status: 401,
86
- statusText: 'Unauthorized'
87
  });
88
  }
89
 
 
2
  import { StreamingTextResponse, parseStreamPart } from 'ai';
3
  import { streamText } from '~/lib/.server/llm/stream-text';
4
  import { stripIndents } from '~/utils/stripIndent';
5
+ import type { ProviderInfo } from '~/types/model';
6
 
7
  const encoder = new TextEncoder();
8
  const decoder = new TextDecoder();
 
12
  }
13
 
14
  async function enhancerAction({ context, request }: ActionFunctionArgs) {
15
+ const { message, model, provider, apiKeys } = await request.json<{
16
  message: string;
17
  model: string;
18
+ provider: ProviderInfo;
19
  apiKeys?: Record<string, string>;
20
  }>();
21
 
22
+ const { name: providerName } = provider;
23
+
24
+ // validate 'model' and 'provider' fields
25
  if (!model || typeof model !== 'string') {
26
  throw new Response('Invalid or missing model', {
27
  status: 400,
28
+ statusText: 'Bad Request',
29
  });
30
  }
31
 
32
+ if (!providerName || typeof providerName !== 'string') {
33
  throw new Response('Invalid or missing provider', {
34
  status: 400,
35
+ statusText: 'Bad Request',
36
  });
37
  }
38
 
 
41
  [
42
  {
43
  role: 'user',
44
+ content:
45
+ `[Model: ${model}]\n\n[Provider: ${providerName}]\n\n` +
46
+ stripIndents`
47
  I want you to improve the user prompt that is wrapped in \`<original_prompt>\` tags.
48
 
49
  IMPORTANT: Only respond with the improved prompt and nothing else!
 
56
  ],
57
  context.cloudflare.env,
58
  undefined,
59
+ apiKeys,
60
  );
61
 
62
  const transformStream = new TransformStream({
63
  transform(chunk, controller) {
64
  const text = decoder.decode(chunk);
65
+ const lines = text.split('\n').filter((line) => line.trim() !== '');
66
+
67
  for (const line of lines) {
68
  try {
69
  const parsed = parseStreamPart(line);
70
+
71
  if (parsed.type === 'text') {
72
  controller.enqueue(encoder.encode(parsed.value));
73
  }
74
  } catch (e) {
75
+ // skip invalid JSON lines
76
+ console.warn('Failed to parse stream part:', line, e);
77
  }
78
  }
79
  },
 
88
  if (error instanceof Error && error.message?.includes('API key')) {
89
  throw new Response('Invalid or missing API key', {
90
  status: 401,
91
+ statusText: 'Unauthorized',
92
  });
93
  }
94