|
1 | 1 | @model AssistViewDemo.Controllers.IndexViewModel |
2 | 2 | @{ |
3 | | - ViewData["Title"] = "AI Assistance with Ollama"; |
| 3 | + ViewData["Title"] = "AI Assistance"; |
4 | 4 | } |
5 | 5 |
|
6 | | -<link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/28.1.41/material.css" /> |
7 | | -<script src="https://cdn.syncfusion.com/ej2/28.1.41/dist/ej2.min.js"></script> |
8 | | - |
9 | 6 | <div class="aiassist-container" style="height: 350px; width: 650px;"> |
10 | | - <ejs-aiassistview id="aiAssistView" bannerTemplate="#bannerContent" promptSuggestions="@Model.PromptSuggestionData" promptRequest="onPromptRequest" created="onCreated"> |
| 7 | + <ejs-aiassistview id="aiAssistView" bannerTemplate="#bannerContent" promptSuggestions="@Model.PromptSuggestionData" promptRequest="onPromptRequest" created="onCreated" stopRespondingClick="handleStopResponse"> |
11 | 8 | <e-aiassistview-toolbarsettings items="@Model.Items" itemClicked="toolbarItemClicked"></e-aiassistview-toolbarsettings> |
12 | 9 | </ejs-aiassistview> |
13 | 10 | </div> |
14 | | - |
15 | 11 | <script id="bannerContent" type="text/x-jsrender"> |
16 | 12 | <div class="banner-content"> |
17 | 13 | <div class="e-icons e-assistview-icon"></div> |
|
28 | 24 | function onCreated() { |
29 | 25 | assistObj = this; |
30 | 26 | } |
31 | | - |
| 27 | + var stopStreaming = false; |
| 28 | + function handleStopResponse() { |
| 29 | + stopStreaming = true; |
| 30 | + } |
32 | 31 | function toolbarItemClicked(args) { |
33 | | - if (args.item.iconCss === 'e-icons e-refresh') { |
34 | | - this.prompts = []; |
35 | | - this.promptSuggestions = suggestions; |
36 | | - } |
| 32 | + if (args.item.iconCss === 'e-icons e-refresh') { |
| 33 | + this.prompts = []; |
| 34 | + this.promptSuggestions = suggestions; |
37 | 35 | } |
38 | | - |
| 36 | + } |
39 | 37 | function onPromptRequest(args) { |
40 | 38 | setTimeout(async () => { |
41 | 39 | let responseText = ''; |
|
45 | 43 | headers: { 'Content-Type': 'application/json' }, |
46 | 44 | body: JSON.stringify({ prompt: args.prompt }) |
47 | 45 | }); |
48 | | - |
49 | 46 | if (!response.ok) { |
50 | 47 | throw new Error(`HTTP ${response.status}: ${response.statusText}`); |
51 | 48 | } |
52 | | - |
53 | | - responseText = await response.json(); |
54 | | - assistObj.addPromptResponse(marked.parse(responseText)); |
| 49 | + const data = await response.json(); |
| 50 | + responseText = data; // Adjust to data.response if the JSON is { response: "text" } |
| 51 | + let current = ''; |
| 52 | + let i = 0; |
| 53 | + const typingSpeed = 15; // ms per character; adjust as needed |
| 54 | + const interval = setInterval(() => { |
| 55 | + if (i < responseText.length && !stopStreaming) { |
| 56 | + current += responseText.charAt(i); |
| 57 | + assistObj.addPromptResponse(marked.parse(current), false); |
| 58 | + i++; |
| 59 | + } else { |
| 60 | + assistObj.addPromptResponse(marked.parse(current), true); |
| 61 | + clearInterval(interval); |
| 62 | + } |
| 63 | + }, typingSpeed); |
55 | 64 | } catch (error) { |
56 | | - assistObj.addPromptResponse('⚠️ Something went wrong while connecting to the AI service. Please try again later.'); |
| 65 | + assistObj.addPromptResponse('⚠️ Something went wrong while connecting to the AI service. Please try again later.', true); |
57 | 66 | } |
58 | 67 | }, 2000); // Match the 2000ms delay from the reference sample |
59 | 68 | } |
60 | 69 | </script> |
61 | | - |
62 | 70 | <style> |
63 | 71 | .aiassist-container .e-view-container { |
64 | 72 | margin: auto; |
|
0 commit comments