Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions actions/knowledge/knowledge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export async function firstIngestion(

export async function ensureFilesIngested(
files: string[],
updateOnly: boolean,
scriptId: string,
token: string
): Promise<string> {
Expand All @@ -69,19 +70,21 @@ export async function ensureFilesIngested(
}
}

try {
const filesInDir = await fs.promises.readdir(dir);
for (const fileName of filesInDir) {
const fullPath = path.join(dir, fileName);
const fileInDroppedFiles = files.find(
(file) => path.basename(file) === path.basename(fullPath)
);
if (!fileInDroppedFiles || !files || files.length === 0) {
await fs.promises.unlink(fullPath);
if (!updateOnly) {
try {
const filesInDir = await fs.promises.readdir(dir);
for (const fileName of filesInDir) {
const fullPath = path.join(dir, fileName);
const fileInDroppedFiles = files.find(
(file) => path.basename(file) === path.basename(fullPath)
);
if (!fileInDroppedFiles || !files || files.length === 0) {
await fs.promises.unlink(fullPath);
}
}
} catch (error) {
return `Error deleting files: ${error}`;
}
} catch (error) {
return `Error deleting files: ${error}`;
}

try {
Expand Down
31 changes: 31 additions & 0 deletions actions/knowledge/util.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { ToolDef } from '@gptscript-ai/gptscript';
import { getKnowledgeBinaryPath } from '@/actions/knowledge/knowledge';

export const KNOWLEDGE_NAME = 'file-retrieval';

export function gatewayTool(): string {
return 'github.com/gptscript-ai/knowledge@v0.4.10-gateway.7';
}
Expand All @@ -13,3 +18,29 @@ export function getCookie(name: string): string {
}
return '';
}

export async function assistantKnowledgeTool(
scriptId: number,
topK: number
): Promise<ToolDef> {
const knowledgePath = await getKnowledgeBinaryPath();
return {
name: KNOWLEDGE_NAME,
description:
'Retrieve information from files uploaded to the assistant. Use it to answer questions from the user and ALWAYS give a proper citation to the best of your abilities, including the source references (filename, page, etc.).',
type: 'tool',
credentials: [
'github.com/gptscript-ai/gateway-creds as github.com/gptscript-ai/gateway',
],
arguments: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Query to search in a knowledge base',
},
},
},
instructions: `#!${knowledgePath} retrieve --dataset ${scriptId.toString()} --top-k ${topK} "\${QUERY}"`,
} as ToolDef;
}
7 changes: 7 additions & 0 deletions actions/upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ export async function deleteKnowledgeFile(workspace: string, name: string) {
return deleteFile(path.join(path.dirname(workspace), 'knowledge', name));
}

export async function clearThreadKnowledge(workspace: string) {
return fs.rm(path.join(path.dirname(workspace), 'knowledge'), {
recursive: true,
force: true,
});
}

export async function lsFiles(dir: string): Promise<string> {
let files: Dirent[] = [];
try {
Expand Down
32 changes: 28 additions & 4 deletions components/chat/useChatSocket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import {
import { Message, MessageType } from './messages';
import PromptForm from './messages/promptForm';
import ConfirmForm from './messages/confirmForm';
import { rootTool, stringify } from '@/actions/gptscript';
import { updateScript } from '@/actions/me/scripts';
import { gatewayTool } from '@/actions/knowledge/util';

const useChatSocket = (isEmpty?: boolean) => {
const initiallyTrustedRepos = [
Expand Down Expand Up @@ -264,8 +267,25 @@ const useChatSocket = (isEmpty?: boolean) => {
[]
);

const handleToolAdjusted = (tools: string[]) => {
const handleToolChange = async (
tools: string[],
scriptId?: string,
scriptContent?: Block[]
) => {
setTools(tools);
if (scriptContent) {
// Ensure the knowledge tool isn't set.
const tool = await rootTool(scriptContent);
tool.tools = (tool.tools || []).filter((t) => t !== gatewayTool());
setScriptContent(scriptContent);
if (scriptId) {
const content = await stringify(scriptContent);
await updateScript({
content: content,
id: parseInt(scriptId),
});
}
}
setRunning(true);
};

Expand Down Expand Up @@ -399,9 +419,13 @@ const useChatSocket = (isEmpty?: boolean) => {
(data: { frame: CallFrame; state: any; name?: string }) =>
handleConfirmRequest(data)
);
socket.on('toolAdded', (tools: string[]) => handleToolAdjusted(tools));
socket.on('toolRemoved', (tools: string[]) => handleToolAdjusted(tools));
socket.on('scriptSaved', (tools: string[]) => handleToolAdjusted(tools));
socket.on('toolAdded', (tools: string[]) => handleToolChange(tools));
socket.on('toolRemoved', (tools: string[]) => handleToolChange(tools));
socket.on(
'scriptSaved',
(scriptId: string, script: Block[], tools: string[]) =>
handleToolChange(tools, scriptId, script)
);
socket.on(
'loaded',
(data: {
Expand Down
3 changes: 2 additions & 1 deletion components/edit/configure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Loading from '@/components/loading';
import Models from '@/components/edit/configure/models';
import Visibility from '@/components/edit/configure/visibility';
import Code from '@/components/edit/configure/code';
import { EditContext, KNOWLEDGE_NAME } from '@/contexts/edit';
import { EditContext } from '@/contexts/edit';
import { GoLightBulb, GoTrash } from 'react-icons/go';
import { HiCog } from 'react-icons/hi2';
import { LuCircuitBoard } from 'react-icons/lu';
Expand All @@ -29,6 +29,7 @@ import { IoMdAdd, IoMdRefresh } from 'react-icons/io';
import { RiFileSearchLine } from 'react-icons/ri';
import FileSettingModals from '@/components/knowledge/KnowledgeModals';
import { RiFoldersLine } from 'react-icons/ri';
import { KNOWLEDGE_NAME } from '@/actions/knowledge/util';

interface ConfigureProps {
collapsed?: boolean;
Expand Down
Loading