diff --git a/AIClasses/Gemini/Gemini.ts b/AIClasses/Gemini/Gemini.ts
index c2efc7d..c775ece 100644
--- a/AIClasses/Gemini/Gemini.ts
+++ b/AIClasses/Gemini/Gemini.ts
@@ -71,11 +71,19 @@ export class Gemini implements IAIClass {
text: this.aiPrompt.systemInstruction()
},
{
- text: `IMPORTANT: When you need current information from the web (recent events, news, current prices, weather, etc.), you should:
- 1. First call the 'request_web_search' function to indicate you need web access
- 2. After that, you'll be given access to Google Search
- 3. Once you have the information from the search, you can answer the user's question
- 4. Subsequent communication will return to providing custom function calls`
+ text: `## IMPORTANT: Web Search Directive
+ **You *must* proactively use the web search tool whenever a user's query requires current, real-time, or frequently changing information.** This includes, but is not limited to:
+ - Current date or time.
+ - Current weather conditions or forecasts.
+ - Recent news, events, or happenings.
+ - Up-to-date prices, statistics, or factual data that is dynamic.
+ - Any information where "current," "latest," or "today's" is implied or explicitly requested.
+
+ When you need current information from the web, you *must* follow these steps:
+ 1. First call the \`request_web_search\` function with a clear and concise \`reasoning\` explaining why web search is needed.
+ 2. After calling this, you will be given access to Google Search.
+ 3. Once you have obtained the necessary information from the search results, use it to formulate your complete and accurate answer.
+ 4. Subsequent interactions will revert to standard function calls or general assistance as appropriate.`
},
{
text: await this.aiPrompt.userInstruction()
diff --git a/Components/ChatArea.svelte b/Components/ChatArea.svelte
index bc52f46..94884cc 100644
--- a/Components/ChatArea.svelte
+++ b/Components/ChatArea.svelte
@@ -171,22 +171,32 @@
{:else}
+ {#if isStreaming && messageIndex === messages.length - 1}
+
+ {#if message.content && message.content !== ''}
-
-
- {#if isStreaming && messageIndex === messages.length - 1}
+
-
-
- {:else}
-
- {@html getStaticHTML(message, messageIndex)}
- {/if}
{/if}
+
+
+ {:else}
+
+ {#if message.content && message.content !== ''}
+
+
+
+ {@html getStaticHTML(message, messageIndex)}
+
+
+
+ {/if}
+ {/if}
+ {/if}
{/if}
{/each}
diff --git a/Components/ChatWindow.svelte b/Components/ChatWindow.svelte
index 7d74693..a5312d0 100644
--- a/Components/ChatWindow.svelte
+++ b/Components/ChatWindow.svelte
@@ -97,6 +97,7 @@
: msg
);
isStreaming = false;
+ await conversationService.saveConversation(conversation);
break;
}
@@ -115,12 +116,17 @@
if (chunk.isComplete) {
isStreaming = false;
- conversation.contents = conversation.contents.map((msg, messageIndex) =>
- messageIndex === aiMessageIndex
- ? { ...msg, content: accumulatedContent }
- : msg
- );
-
+ // Only save the message if it has content or a function call
+ if (accumulatedContent.trim() !== "" || capturedFunctionCall) {
+ conversation.contents = conversation.contents.map((msg, messageIndex) =>
+ messageIndex === aiMessageIndex
+ ? { ...msg, content: accumulatedContent }
+ : msg
+ );
+ } else {
+ // Remove the empty placeholder message
+ conversation.contents = conversation.contents.filter((_, messageIndex) => messageIndex !== aiMessageIndex);
+ }
await conversationService.saveConversation(conversation);
}
}
diff --git a/Enums/AIFunction.ts b/Enums/AIFunction.ts
index 130eb6d..b32dd69 100644
--- a/Enums/AIFunction.ts
+++ b/Enums/AIFunction.ts
@@ -1,3 +1,5 @@
export enum AIFunction {
- ListVaultFiles = "list_vault_files"
+ ListVaultFiles = "list_vault_files",
+
+ RequestWebSearch = "request_web_search"
}
\ No newline at end of file
diff --git a/Services/AIFunctionService.ts b/Services/AIFunctionService.ts
index 613bf3a..3276aa0 100644
--- a/Services/AIFunctionService.ts
+++ b/Services/AIFunctionService.ts
@@ -13,10 +13,12 @@ export class AIFunctionService {
public async performAIFunction(functionCall: AIFunctionCall): Promise
{
switch (functionCall.name) {
case AIFunction.ListVaultFiles:
- return new AIFunctionResponse(
- functionCall.name,
- await this.listVaultFiles()
- );
+ return new AIFunctionResponse(functionCall.name, await this.listVaultFiles());
+
+ // this is only used by gemini
+ case AIFunction.RequestWebSearch:
+ return new AIFunctionResponse(functionCall.name, {})
+
default:
const error = `Unknown function request ${functionCall.name}`
console.error(error);
diff --git a/Services/ConversationFileSystemService.ts b/Services/ConversationFileSystemService.ts
index 90d11dd..0eaa520 100644
--- a/Services/ConversationFileSystemService.ts
+++ b/Services/ConversationFileSystemService.ts
@@ -77,7 +77,7 @@ export class ConversationFileSystemService {
conversation.created = new Date(data.created);
conversation.contents = data.contents.map(content => {
return new ConversationContent(
- content.role, content.content, new Date(content.timestamp), content.isFunctionCall);
+ content.role, content.content, new Date(content.timestamp), content.isFunctionCall, content.isFunctionCallResponse);
});
conversations.push(conversation);
}