|
| 1 | +/* |
| 2 | + * Copyright Red Hat, Inc. |
| 3 | + * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + * you may not use this file except in compliance with the License. |
| 6 | + * You may obtain a copy of the License at |
| 7 | + * |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | + * |
| 10 | + * Unless required by applicable law or agreed to in writing, software |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + * See the License for the specific language governing permissions and |
| 14 | + * limitations under the License. |
| 15 | + */ |
| 16 | + |
| 17 | +import { http, HttpResponse } from 'msw'; |
| 18 | + |
| 19 | +export const LOCAL_RCS_ADDR = 'http://0.0.0.0:8080'; |
| 20 | + |
| 21 | +function loadTestFixture(filePathFromFixturesDir: string) { |
| 22 | + return require(`${__dirname}/${filePathFromFixturesDir}`); |
| 23 | +} |
| 24 | + |
| 25 | +const mockConversationId = 'conversation-id-1'; |
| 26 | +const mockConversationId2 = `conversation-id-2`; |
| 27 | +const conversation1History = [ |
| 28 | + { |
| 29 | + content: 'what is openshit lightspeed', |
| 30 | + response_metadata: { |
| 31 | + created_at: 1741287754.162095, |
| 32 | + }, |
| 33 | + type: 'human', |
| 34 | + }, |
| 35 | + { |
| 36 | + content: |
| 37 | + "OpenShift Lightspeed is a generative AI assistant integrated into the Red Hat Developer Hub (RHDH), an internal developer portal built on CNCF Backstage. It enhances developer productivity by streamlining workflows, providing instant access to technical knowledge, and supporting developers in their day-to-day tasks.\n\nOpenShift Lightspeed offers various features such as code assistance, knowledge retrieval, system navigation, troubleshooting, and integration support. It can generate, debug, and optimize code snippets, provide instant access to internal and external documentation, offer step-by-step instructions for Red Hat Developer Hub features, diagnose issues in services, pipelines, and configurations with actionable recommendations, and assist with Backstage plugins and integrations, including Kubernetes, CI/CD, and GitOps pipelines.\n\nOpenShift Lightspeed is designed to help developers work smarter, solve problems faster, and ensure they can focus on building and deploying software efficiently. It adapts its communication style to match the user's technical proficiency, providing concise, technical language for experts and clear explanations with examples for beginners.\n\nOpenShift Lightspeed is well-versed in various domains, including programming languages, DevOps, cloud platforms, Backstage, infrastructure as code, security, and documentation and standards. It leverages Markdown to format code snippets, tables, and lists for readability in its responses.", |
| 38 | + response_metadata: { |
| 39 | + created_at: 1741287761.8619468, |
| 40 | + provider: 'my_ollama', |
| 41 | + model: 'granite3-dense:8b', |
| 42 | + }, |
| 43 | + type: 'ai', |
| 44 | + }, |
| 45 | +]; |
| 46 | + |
| 47 | +const conversation2History = [ |
| 48 | + { |
| 49 | + content: 'Hello', |
| 50 | + response_metadata: { |
| 51 | + created_at: 1741287754.162095, |
| 52 | + }, |
| 53 | + type: 'human', |
| 54 | + }, |
| 55 | + { |
| 56 | + content: 'ai dummy response for test purpose', |
| 57 | + response_metadata: { |
| 58 | + created_at: 1741287761.8619468, |
| 59 | + provider: 'my_ollama', |
| 60 | + model: 'granite3-dense:8b', |
| 61 | + }, |
| 62 | + type: 'ai', |
| 63 | + }, |
| 64 | +]; |
| 65 | + |
| 66 | +export const chatHistory: any = {}; |
| 67 | +chatHistory[mockConversationId] = conversation1History; |
| 68 | +chatHistory[mockConversationId2] = conversation2History; |
| 69 | + |
| 70 | +export const rcsHandlers = [ |
| 71 | + http.post(`${LOCAL_RCS_ADDR}/v1/streaming_query`, () => { |
| 72 | + const textEncoder = new TextEncoder(); |
| 73 | + const mockData = loadTestFixture('chatResponse.json'); |
| 74 | + |
| 75 | + const stream = new ReadableStream({ |
| 76 | + start(controller) { |
| 77 | + mockData.forEach((chunk: any) => { |
| 78 | + controller.enqueue( |
| 79 | + textEncoder.encode(`data: ${JSON.stringify(chunk)}\n\n`), |
| 80 | + ); |
| 81 | + }); |
| 82 | + controller.close(); |
| 83 | + }, |
| 84 | + }); |
| 85 | + |
| 86 | + return new HttpResponse(stream, { |
| 87 | + headers: { |
| 88 | + 'Content-Type': 'text/plain', |
| 89 | + }, |
| 90 | + }); |
| 91 | + }), |
| 92 | + |
| 93 | + http.get(`${LOCAL_RCS_ADDR}/conversations/:conversation_id`, ({ params }) => { |
| 94 | + const conversation_id = params.conversation_id as string; |
| 95 | + if (conversation_id in chatHistory) { |
| 96 | + const mockHistoryRes = { |
| 97 | + chat_history: chatHistory[conversation_id], |
| 98 | + }; |
| 99 | + return HttpResponse.json(mockHistoryRes); |
| 100 | + } |
| 101 | + return new HttpResponse( |
| 102 | + JSON.stringify({ |
| 103 | + error: `Conversation ${conversation_id} not found`, |
| 104 | + }), |
| 105 | + { |
| 106 | + status: 500, |
| 107 | + headers: { 'Content-Type': 'application/json' }, |
| 108 | + }, |
| 109 | + ); |
| 110 | + }), |
| 111 | + |
| 112 | + http.get(`${LOCAL_RCS_ADDR}/conversations`, () => { |
| 113 | + const conversations = []; |
| 114 | + const ids = Object.keys(chatHistory); |
| 115 | + for (const id of ids) { |
| 116 | + const conversation = { |
| 117 | + conversation_id: id, |
| 118 | + topic_summary: 'dummy summary', |
| 119 | + last_message_timestamp: 1742237500.516723, |
| 120 | + }; |
| 121 | + conversations.push(conversation); |
| 122 | + } |
| 123 | + const mockConversations = { |
| 124 | + conversations: conversations, |
| 125 | + }; |
| 126 | + |
| 127 | + return HttpResponse.json(mockConversations); |
| 128 | + }), |
| 129 | + |
| 130 | + http.delete( |
| 131 | + `${LOCAL_RCS_ADDR}/conversations/:conversation_id`, |
| 132 | + ({ params }) => { |
| 133 | + const conversation_id = params.conversation_id as string; |
| 134 | + if (conversation_id in chatHistory) { |
| 135 | + delete chatHistory[conversation_id]; |
| 136 | + return HttpResponse.json('ok', { status: 200 }); |
| 137 | + } |
| 138 | + return new HttpResponse( |
| 139 | + JSON.stringify({ |
| 140 | + error: `Conversation ${conversation_id} not found`, |
| 141 | + }), |
| 142 | + { |
| 143 | + status: 500, |
| 144 | + headers: { 'Content-Type': 'application/json' }, |
| 145 | + }, |
| 146 | + ); |
| 147 | + }, |
| 148 | + ), |
| 149 | + |
| 150 | + http.get(`${LOCAL_RCS_ADDR}/conversations`, () => { |
| 151 | + const mockModelRes = { |
| 152 | + conversations: [ |
| 153 | + { |
| 154 | + conversation_id: 'c0a3bc27-77cc-46da-822f-93a9c0e0de5b', |
| 155 | + topic_summary: 'LIGHTSPEED CONCEPT', |
| 156 | + last_message_timestamp: 1741289312.209488, |
| 157 | + }, |
| 158 | + { |
| 159 | + conversation_id: 'e6df4804-5ada-4138-9dfb-4ba515beb4c5', |
| 160 | + topic_summary: 'AI Topic Summarizer Capability', |
| 161 | + last_message_timestamp: 1741289568.360167, |
| 162 | + }, |
| 163 | + { |
| 164 | + conversation_id: '933bb6e3-35d3-453a-88fc-b387175f2979', |
| 165 | + topic_summary: 'OpenShift Overview', |
| 166 | + last_message_timestamp: 1741289606.5125692, |
| 167 | + }, |
| 168 | + ], |
| 169 | + }; |
| 170 | + return HttpResponse.json(mockModelRes); |
| 171 | + }), |
| 172 | + |
| 173 | + // Catch-all handler for unknown paths |
| 174 | + http.all(`${LOCAL_RCS_ADDR}/*`, ({ request }) => { |
| 175 | + console.log(`Caught request to unknown path: ${request.url}`); |
| 176 | + |
| 177 | + // Return a 404 response |
| 178 | + return new HttpResponse( |
| 179 | + JSON.stringify({ |
| 180 | + error: 'Not found', |
| 181 | + message: `The requested resource at ${request.url} was not found`, |
| 182 | + }), |
| 183 | + { |
| 184 | + status: 404, |
| 185 | + headers: { 'Content-Type': 'application/json' }, |
| 186 | + }, |
| 187 | + ); |
| 188 | + }), |
| 189 | +]; |
0 commit comments