|
3 | 3 | import { fly } from 'svelte/transition';
|
4 | 4 | import { _ } from 'svelte-i18n';
|
5 | 5 | import util from "lodash";
|
6 |
| - import { Button, Col, Row } from '@sveltestrap/sveltestrap'; |
| 6 | + import { Button, Card, CardBody, Col, Row } from '@sveltestrap/sveltestrap'; |
7 | 7 | import LoadingDots from '$lib/common/LoadingDots.svelte';
|
8 | 8 | import HeadTitle from '$lib/common/HeadTitle.svelte';
|
9 | 9 | import Breadcrumb from '$lib/common/Breadcrumb.svelte';
|
10 | 10 | import Markdown from '$lib/common/markdown/Markdown.svelte';
|
11 |
| - import InstructionSetting from './instruction-components/instruction-setting.svelte'; |
12 | 11 | import InstructionState from './instruction-components/instruction-state.svelte';
|
13 | 12 | import { getAgents } from '$lib/services/agent-service';
|
14 | 13 | import LoadingToComplete from '$lib/common/LoadingToComplete.svelte';
|
15 | 14 | import { sendChatCompletion } from '$lib/services/instruct-service';
|
16 | 15 | import { getLlmConfigs } from '$lib/services/llm-provider-service';
|
17 | 16 | import { LlmModelType } from '$lib/helpers/enums';
|
| 17 | + import NavBar from '$lib/common/nav-bar/NavBar.svelte'; |
| 18 | + import NavItem from '$lib/common/nav-bar/NavItem.svelte'; |
| 19 | + import InstructionTemplate from './instruction-components/instruction-template.svelte'; |
| 20 | + import InstructionLlm from './instruction-components/instruction-llm.svelte'; |
18 | 21 |
|
19 | 22 | const maxLength = 64000;
|
20 | 23 | const DEFAULT_PROVIDER = 'openai';
|
21 | 24 | const DEFAULT_MODEL = 'gpt-4o-mini';
|
22 | 25 |
|
| 26 | + /** @type {any[]}*/ |
| 27 | + const tabs = [ |
| 28 | + { name: 'instruction-template', displayText: 'Template' }, |
| 29 | + { name: 'instruction-llm', displayText: 'LLM Config' }, |
| 30 | + { name: 'instruction-states', displayText: 'States' } |
| 31 | + ]; |
| 32 | +
|
23 | 33 | let isLoading = false;
|
24 | 34 | let isThinking = false;
|
25 | 35 | let requestDone = false;
|
|
32 | 42 | /** @type {import('$agentTypes').AgentModel | null} */
|
33 | 43 | let selectedAgent = null;
|
34 | 44 |
|
35 |
| - /** @type {string | null} */ |
| 45 | + /** @type {import('$commonTypes').LlmConfig?} */ |
36 | 46 | let selectedProvider = null;
|
37 | 47 |
|
38 | 48 | /** @type {string | null} */
|
|
49 | 59 | { key: '', value: ''}
|
50 | 60 | ];
|
51 | 61 |
|
| 62 | + /** @type {string}*/ |
| 63 | + let selectedTab = tabs[0].name; |
| 64 | +
|
52 | 65 | onMount(async () => {
|
53 | 66 | try {
|
54 | 67 | isLoading = true;
|
|
62 | 75 | }
|
63 | 76 | });
|
64 | 77 |
|
65 |
| -
|
66 | 78 | function sendRequest() {
|
67 | 79 | isThinking = true;
|
68 | 80 | requestDone = false;
|
|
73 | 85 | text: util.trim(text) || '',
|
74 | 86 | instruction: util.trim(instruction) || null,
|
75 | 87 | agentId: selectedAgent?.id,
|
76 |
| - provider: selectedProvider || DEFAULT_PROVIDER, |
| 88 | + provider: selectedProvider?.provider || DEFAULT_PROVIDER, |
77 | 89 | model: selectedModel || DEFAULT_MODEL,
|
78 | 90 | states: formattedStates
|
79 | 91 | }).then(res => {
|
|
121 | 133 |
|
122 | 134 | /** @param {any} e */
|
123 | 135 | function onAgentSelected(e) {
|
124 |
| - selectedAgent = e.detail.selectedAgent || null; |
| 136 | + selectedAgent = e.detail.agent || null; |
125 | 137 | instruction = selectedAgent?.instruction || '';
|
126 | 138 |
|
127 |
| - const template = e.detail.selectedTemplate || null; |
| 139 | + const template = e.detail.template || null; |
128 | 140 | if (!!template) {
|
129 | 141 | instruction = template?.content || '';
|
130 | 142 | }
|
131 | 143 |
|
132 |
| - onLlmSelected(e); |
| 144 | + const providerName = selectedAgent?.llm_config?.provider || null; |
| 145 | + const modelName = selectedAgent?.llm_config?.model || null; |
| 146 | + selectedProvider = llmConfigs?.find(x => x.provider === providerName) || null; |
| 147 | + selectedModel = modelName; |
133 | 148 | }
|
134 | 149 |
|
135 | 150 | /** @param {any} e */
|
136 | 151 | function onLlmSelected(e) {
|
137 |
| - selectedProvider = e.detail.selectedProvider || null; |
138 |
| - selectedModel = e.detail.selectedModel || ''; |
| 152 | + selectedProvider = e.detail.provider || null; |
| 153 | + selectedModel = e.detail.model || ''; |
| 154 | + } |
| 155 | +
|
| 156 | + /** @param {string} selected */ |
| 157 | + function handleTabClick(selected) { |
| 158 | + selectedTab = selected; |
139 | 159 | }
|
140 | 160 | </script>
|
141 | 161 |
|
|
151 | 171 | rows={8}
|
152 | 172 | maxlength={maxLength}
|
153 | 173 | disabled={isThinking}
|
154 |
| - placeholder={'Start typing here...'} |
| 174 | + placeholder={'Enter input message...'} |
155 | 175 | bind:value={text}
|
156 | 176 | on:keydown={(e) => pressKey(e)}
|
157 | 177 | />
|
|
207 | 227 | </div>
|
208 | 228 | </div>
|
209 | 229 |
|
210 |
| -
|
211 |
| -<div class="d-xl-flex mt-3"> |
212 |
| - <div class="w-100"> |
213 |
| - <InstructionSetting |
214 |
| - disabled={isThinking} |
215 |
| - agents={agents} |
216 |
| - llmConfigs={llmConfigs} |
217 |
| - on:agentSelected={e => onAgentSelected(e)} |
218 |
| - on:llmSelected={e => onLlmSelected(e)} |
219 |
| - /> |
220 |
| - </div> |
221 |
| -</div> |
222 |
| -
|
223 |
| -
|
224 | 230 | <div class="d-xl-flex mt-4 mb-5">
|
225 | 231 | <div class="w-100">
|
| 232 | + <Row> |
| 233 | + <Col lg="7"> |
| 234 | + <div class="instruct-text-header text-primary fw-bold mb-2"> |
| 235 | + <div class="line-align-center"> |
| 236 | + {'Instruction'} |
| 237 | + </div> |
| 238 | + <div class="line-align-center"> |
| 239 | + <!-- svelte-ignore a11y-click-events-have-key-events --> |
| 240 | + <!-- svelte-ignore a11y-no-static-element-interactions --> |
| 241 | + <i |
| 242 | + class="mdi mdi-refresh text-primary clickable" |
| 243 | + data-bs-toggle="tooltip" |
| 244 | + data-bs-placement="bottom" |
| 245 | + title={'Reset'} |
| 246 | + on:click={e => resetInstruction()} |
| 247 | + /> |
| 248 | + </div> |
| 249 | + </div> |
| 250 | + </Col> |
| 251 | + <Col lg="5"></Col> |
| 252 | + </Row> |
226 | 253 | <Row class="instruct-setting-container">
|
227 |
| - <Col lg="9"> |
| 254 | + <Col lg="7"> |
228 | 255 | <div>
|
229 |
| - <div class="instruct-text-header text-primary fw-bold mb-2"> |
230 |
| - <div class="line-align-center"> |
231 |
| - {'Instruction'} |
232 |
| - </div> |
233 |
| - <div class="line-align-center"> |
234 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
235 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
236 |
| - <i |
237 |
| - class="mdi mdi-refresh text-primary clickable" |
238 |
| - data-bs-toggle="tooltip" |
239 |
| - data-bs-placement="bottom" |
240 |
| - title={'Reset'} |
241 |
| - on:click={e => resetInstruction()} |
242 |
| - /> |
243 |
| - </div> |
244 |
| - </div> |
245 |
| - <div class="instruct-setting-section instruction-border instruct-setting-padding"> |
| 256 | + <div class="instruct-setting-section" style="gap: 2px;"> |
246 | 257 | <textarea
|
247 | 258 | class='form-control knowledge-textarea'
|
248 | 259 | rows={19}
|
249 | 260 | maxlength={maxLength}
|
250 | 261 | disabled={isThinking}
|
251 |
| - placeholder={'Start typing here...'} |
| 262 | + placeholder={'Enter instruction...'} |
252 | 263 | bind:value={instruction}
|
253 | 264 | />
|
| 265 | + <div class="text-secondary text-end text-count"> |
| 266 | + <div>{instruction?.length || 0}/{maxLength}</div> |
| 267 | + </div> |
254 | 268 | </div>
|
255 | 269 | </div>
|
256 | 270 | </Col>
|
257 |
| - <Col lg="3"> |
258 |
| - <InstructionState bind:states={states} disabled={isThinking} /> |
| 271 | + <Col lg="5" class="instruction-gap"> |
| 272 | + <Card> |
| 273 | + <CardBody> |
| 274 | + |
| 275 | + <NavBar |
| 276 | + id={'instruction-nav-container'} |
| 277 | + disableDefaultStyles |
| 278 | + containerClasses={'nav-tabs-secondary'} |
| 279 | + > |
| 280 | + {#each tabs as tab, idx} |
| 281 | + <NavItem |
| 282 | + containerStyles={`flex: 0 1 calc(100% / ${tabs.length <= 2 ? tabs.length : 3})`} |
| 283 | + navBtnStyles={'text-transform: none;'} |
| 284 | + navBtnId={`${tab.name}-tab`} |
| 285 | + dataBsTarget={`#${tab.name}-tab-pane`} |
| 286 | + ariaControls={`${tab.name}-tab-pane`} |
| 287 | + navBtnText={tab.displayText} |
| 288 | + active={tab.name === selectedTab} |
| 289 | + onClick={() => handleTabClick(tab.name)} |
| 290 | + /> |
| 291 | + {/each} |
| 292 | + </NavBar> |
| 293 | + |
| 294 | + <div class:hide={selectedTab !== 'instruction-template'}> |
| 295 | + <InstructionTemplate |
| 296 | + agents={agents} |
| 297 | + disabled={isThinking} |
| 298 | + on:agentSelected={e => onAgentSelected(e)} |
| 299 | + /> |
| 300 | + </div> |
| 301 | + <div class:hide={selectedTab !== 'instruction-llm'}> |
| 302 | + <InstructionLlm |
| 303 | + llmConfigs={llmConfigs} |
| 304 | + disabled={isThinking} |
| 305 | + selectedProvider={selectedProvider} |
| 306 | + selectedModel={selectedModel} |
| 307 | + on:llmSelected={e => onLlmSelected(e)} |
| 308 | + /> |
| 309 | + </div> |
| 310 | + <div class:hide={selectedTab !== 'instruction-states'}> |
| 311 | + <InstructionState |
| 312 | + bind:states={states} |
| 313 | + disabled={isThinking} |
| 314 | + /> |
| 315 | + </div> |
| 316 | + </CardBody> |
| 317 | + </Card> |
| 318 | + |
259 | 319 | </Col>
|
260 | 320 | </Row>
|
261 | 321 | </div>
|
|
0 commit comments