Skip to content

Commit fcf7925

Browse files
authored
Merge pull request #4 from jrobertboos/main
Enhance Lightspeed Chatbot functionality and documentation
2 parents 18e04f4 + 1612981 commit fcf7925

File tree

4 files changed

+47
-14
lines changed

4 files changed

+47
-14
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ A reference implementation of a chatbot interface built with React, TypeScript,
1515

1616
## 🚀 Quick Start
1717

18+
**Prerequisites**: Ensure the [lightspeed-stack](https://github.com/lightspeed-core/lightspeed-stack) is running to provide the backend API services.
19+
20+
If you need help getting `lightspeed-stack` running follow this [guide](https://github.com/lightspeed-core/lightspeed-stack/blob/main/docs/getting_started.md).
21+
1822
```bash
1923
git clone https://github.com/your-org/lightspeed-reference-ui
2024
cd lightspeed-reference-ui
@@ -166,6 +170,7 @@ Body: {
166170
Response: Server-Sent Events stream with events:
167171
- start: { conversation_id: string }
168172
- token: { id: number, role: string, token: string }
173+
- tool_call: { id: number, role: string, token: string | Record<string, any> }
169174
- end: { referenced_documents: any[], truncated: any, input_tokens: number, output_tokens: number }
170175
```
171176

@@ -245,6 +250,6 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
245250
## 🆘 Support
246251

247252
If you encounter any issues or have questions:
248-
- Check the [Issues](https://github.com/your-org/lightspeed-reference-ui/issues) page
253+
- Check the [Issues](https://github.com/lightspeed-core/lightspeed-reference-ui/issues) page
249254
- Review the component documentation in `src/app/LightspeedChatbot/README.md`
250255
- Refer to the [PatternFly documentation](https://www.patternfly.org/get-started/develop) for UI components

src/app/LightspeedChatbot/hooks/useChatbot.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message';
44
import { Conversation } from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav';
55
import { DropEvent, DropdownItem, DropdownList } from '@patternfly/react-core';
66

7-
import { Model, QueryRequest, StreamTokenData, StreamEndData, ConversationResponse } from '../types';
7+
import { Model, QueryRequest, StreamTokenData, StreamEndData, ConversationResponse, StreamToolCallData } from '../types';
88
import { INITIAL_MESSAGES, INITIAL_CONVERSATIONS, USER_AVATAR, BOT_AVATAR, DEFAULT_SYSTEM_PROMPT } from '../constants';
99
import { fetchModels, sendStreamingQuery, fetchConversation, deleteConversation } from '../services/api';
1010
import { generateId, findMatchingItems, copyToClipboard } from '../utils/helpers';
@@ -41,7 +41,7 @@ export const useChatbot = () => {
4141
// Set first LLM model as default
4242
const defaultModel = models.find((model) => model.api_model_type === 'llm');
4343
if (defaultModel) {
44-
setSelectedModel(defaultModel.identifier);
44+
setSelectedModel(defaultModel.provider_resource_id);
4545
setSelectedProvider(defaultModel.provider_id);
4646
}
4747
};
@@ -148,7 +148,12 @@ export const useChatbot = () => {
148148

149149
// Selection handlers
150150
const onSelectModel = (_event?: React.MouseEvent, value?: string | number) => {
151-
setSelectedModel(value as string);
151+
const selectedIdentifier = value as string;
152+
const selectedModelData = availableModels.find(model => model.identifier === selectedIdentifier);
153+
if (selectedModelData) {
154+
setSelectedModel(selectedModelData.provider_resource_id);
155+
setSelectedProvider(selectedModelData.provider_id);
156+
}
152157
};
153158

154159
const onSelectDisplayMode = (_event?: React.MouseEvent, value?: string | number) => {
@@ -328,6 +333,7 @@ export const useChatbot = () => {
328333
conversation_id: currentConversationId || undefined,
329334
model: selectedModel || undefined,
330335
provider: selectedProvider || undefined,
336+
no_tools: false,
331337
system_prompt: DEFAULT_SYSTEM_PROMPT,
332338
attachments:
333339
attachedFiles.length > 0 && fileContents.length > 0
@@ -347,15 +353,7 @@ export const useChatbot = () => {
347353
queryRequest,
348354
// onToken callback
349355
(token: string, tokenData?: StreamTokenData) => {
350-
if (tokenData && tokenData.role === 'tool_execution') {
351-
currentToolExecutions.push(token);
352-
setToolExecutions((prev) => ({
353-
...prev,
354-
[botMessageId]: [...currentToolExecutions],
355-
}));
356-
} else {
357-
streamingContent += token;
358-
}
356+
streamingContent += token;
359357

360358
setMessages((prevMessages) => {
361359
const updatedMessages = [...prevMessages];
@@ -407,6 +405,23 @@ export const useChatbot = () => {
407405
});
408406
setAnnouncement(`Message from Lightspeed AI: ${streamingContent}`);
409407
},
408+
// onToolCall callback
409+
(toolCallData: StreamToolCallData) => {
410+
console.log('toolCallData', toolCallData);
411+
if (
412+
typeof toolCallData.token === 'object' &&
413+
toolCallData.token !== null &&
414+
typeof toolCallData.token.tool_name === 'string' &&
415+
typeof toolCallData.token.arguments === 'object'
416+
) {
417+
const { tool_name, arguments: toolArgs } = toolCallData.token;
418+
currentToolExecutions.push(`${tool_name}(${JSON.stringify(toolArgs)})`);
419+
}
420+
setToolExecutions((prev) => ({
421+
...prev,
422+
[botMessageId]: [...currentToolExecutions],
423+
}));
424+
},
410425
);
411426
} catch (error) {
412427
console.error('Error sending streaming query:', error);

src/app/LightspeedChatbot/services/api.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
StreamEvent,
77
StreamStartData,
88
StreamTokenData,
9+
StreamToolCallData,
910
StreamEndData,
1011
ConversationResponse,
1112
} from '../types';
@@ -79,6 +80,7 @@ export const sendStreamingQuery = async (
7980
onToken: (token: string, tokenData?: StreamTokenData) => void,
8081
onStart: (conversationId: string) => void,
8182
onEnd: (endData: StreamEndData) => void,
83+
onToolCall: (toolCallData: StreamToolCallData) => void,
8284
): Promise<void> => {
8385
try {
8486
const response = await fetch(`${API_BASE_URL}/v1/streaming_query`, {
@@ -117,6 +119,10 @@ export const sendStreamingQuery = async (
117119
const startData = eventData.data as StreamStartData;
118120
onStart(startData.conversation_id);
119121
break;
122+
case 'tool_call':
123+
const toolCallData = eventData.data as StreamToolCallData;
124+
onToolCall(toolCallData);
125+
break;
120126
case 'token':
121127
const tokenData = eventData.data as StreamTokenData;
122128
onToken(tokenData.token, tokenData);

src/app/LightspeedChatbot/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export interface QueryRequest {
1414
conversation_id?: string;
1515
provider?: string;
1616
model?: string;
17+
no_tools?: boolean;
1718
system_prompt?: string;
1819
attachments?: Array<{
1920
attachment_type: string;
@@ -42,7 +43,7 @@ export interface ConversationResponse {
4243

4344
// Streaming types
4445
export interface StreamEvent {
45-
event: 'start' | 'token' | 'end';
46+
event: 'start' | 'token' | 'tool_call' | 'end';
4647
data: any;
4748
}
4849

@@ -56,6 +57,12 @@ export interface StreamTokenData {
5657
token: string;
5758
}
5859

60+
export interface StreamToolCallData {
61+
id: number;
62+
role: string;
63+
token: string | Record<string, any>;
64+
}
65+
5966
export interface StreamEndData {
6067
referenced_documents: Array<{
6168
doc_url: string;

0 commit comments

Comments
 (0)