add "Fact Triggers" tab in UI
This commit is contained in:
@@ -35,6 +35,7 @@ export default function ChatPage() {
|
|||||||
const systemPrompt = useStore((state) => state.systemPrompt);
|
const systemPrompt = useStore((state) => state.systemPrompt);
|
||||||
const parameters = useStore((state) => state.parameters);
|
const parameters = useStore((state) => state.parameters);
|
||||||
const facts = useStore((state) => state.facts);
|
const facts = useStore((state) => state.facts);
|
||||||
|
const factTriggers = useStore((state) => state.factTriggers);
|
||||||
const loading = useStore((state) => state.loading);
|
const loading = useStore((state) => state.loading);
|
||||||
const setConversationId = useStore((state) => state.setConversationId);
|
const setConversationId = useStore((state) => state.setConversationId);
|
||||||
const setConversationTitle = useStore((state) => state.setConversationTitle);
|
const setConversationTitle = useStore((state) => state.setConversationTitle);
|
||||||
@@ -43,13 +44,16 @@ export default function ChatPage() {
|
|||||||
const setSystemPrompt = useStore((state) => state.setSystemPrompt);
|
const setSystemPrompt = useStore((state) => state.setSystemPrompt);
|
||||||
const setParameters = useStore((state) => state.setParameters);
|
const setParameters = useStore((state) => state.setParameters);
|
||||||
const setFacts = useStore((state) => state.setFacts);
|
const setFacts = useStore((state) => state.setFacts);
|
||||||
|
const setFactTriggers = useStore((state) => state.setFactTriggers);
|
||||||
const removeFact = useStore((state) => state.removeFact);
|
const removeFact = useStore((state) => state.removeFact);
|
||||||
|
const removeFactTrigger = useStore((state) => state.removeFactTrigger);
|
||||||
const setLoading = useStore((state) => state.setLoading);
|
const setLoading = useStore((state) => state.setLoading);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
conversation,
|
conversation,
|
||||||
messages: initialMessages,
|
messages: initialMessages,
|
||||||
facts: initialFacts,
|
facts: initialFacts,
|
||||||
|
factTriggers: initialFactTriggers,
|
||||||
} = useData<Data>();
|
} = useData<Data>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -76,11 +80,20 @@ export default function ChatPage() {
|
|||||||
setFacts(initialFacts);
|
setFacts(initialFacts);
|
||||||
}, [initialFacts, setFacts]);
|
}, [initialFacts, setFacts]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFactTriggers(initialFactTriggers);
|
||||||
|
}, [initialFactTriggers, setFactTriggers]);
|
||||||
|
|
||||||
async function handleDeleteFact(factId: string) {
|
async function handleDeleteFact(factId: string) {
|
||||||
removeFact(factId);
|
removeFact(factId);
|
||||||
await trpc.chat.facts.deleteOne.mutate({ factId });
|
await trpc.chat.facts.deleteOne.mutate({ factId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleDeleteFactTrigger(factTriggerId: string) {
|
||||||
|
removeFactTrigger(factTriggerId);
|
||||||
|
await trpc.chat.factTriggers.deleteOne.mutate({ factTriggerId });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
@@ -105,6 +118,7 @@ export default function ChatPage() {
|
|||||||
<Tabs.Tab value="system-prompt">System Prompt</Tabs.Tab>
|
<Tabs.Tab value="system-prompt">System Prompt</Tabs.Tab>
|
||||||
<Tabs.Tab value="parameters">Parameters</Tabs.Tab>
|
<Tabs.Tab value="parameters">Parameters</Tabs.Tab>
|
||||||
<Tabs.Tab value="facts">Facts</Tabs.Tab>
|
<Tabs.Tab value="facts">Facts</Tabs.Tab>
|
||||||
|
<Tabs.Tab value="fact-triggers">Fact Triggers</Tabs.Tab>
|
||||||
</Tabs.List>
|
</Tabs.List>
|
||||||
<Tabs.Panel value="message">
|
<Tabs.Panel value="message">
|
||||||
<Messages messages={messages} />
|
<Messages messages={messages} />
|
||||||
@@ -193,6 +207,24 @@ export default function ChatPage() {
|
|||||||
))}
|
))}
|
||||||
</List>
|
</List>
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
|
<Tabs.Panel value="fact-triggers">
|
||||||
|
<List>
|
||||||
|
{factTriggers.map((factTrigger) => (
|
||||||
|
<List.Item key={factTrigger.id}>
|
||||||
|
{factTrigger.content}{" "}
|
||||||
|
<IconTrash
|
||||||
|
size={16}
|
||||||
|
stroke={1.5}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
handleDeleteFactTrigger(factTrigger.id);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</List.Item>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</Tabs.Panel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,5 +15,13 @@ export const data = async (pageContext: PageContextServer) => {
|
|||||||
const facts = await caller.facts.fetchByConversationId({
|
const facts = await caller.facts.fetchByConversationId({
|
||||||
conversationId: id,
|
conversationId: id,
|
||||||
});
|
});
|
||||||
return { conversation, messages, facts };
|
|
||||||
|
// Fetch all fact triggers for the conversation's facts
|
||||||
|
const factTriggerPromises = facts.map(fact =>
|
||||||
|
caller.factTriggers.fetchByFactId({ factId: fact.id })
|
||||||
|
);
|
||||||
|
const factTriggersArrays = await Promise.all(factTriggerPromises);
|
||||||
|
const factTriggers = factTriggersArrays.flat();
|
||||||
|
|
||||||
|
return { conversation, messages, facts, factTriggers };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,12 +70,12 @@ export const factTriggers = router({
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.mutation(async ({ input: { factTriggerId } }) => {
|
.mutation(async ({ input: { factTriggerId } }) => {
|
||||||
const deletedFactTriggerIndex = db.data.facts.findIndex(
|
const deletedFactTriggerIndex = db.data.factTriggers.findIndex(
|
||||||
(fact) => fact.id === factTriggerId,
|
(factTrigger) => factTrigger.id === factTriggerId,
|
||||||
);
|
);
|
||||||
if (deletedFactTriggerIndex === -1) throw new Error("Fact not found");
|
if (deletedFactTriggerIndex === -1) throw new Error("Fact trigger not found");
|
||||||
db.data.factTriggers.splice(deletedFactTriggerIndex, 1);
|
db.data.factTriggers.splice(deletedFactTriggerIndex, 1);
|
||||||
db.write();
|
await db.write();
|
||||||
return { ok: true };
|
return { ok: true };
|
||||||
}),
|
}),
|
||||||
generateFromFact: publicProcedure
|
generateFromFact: publicProcedure
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { messages } from "./messages.js";
|
|||||||
import { facts, createCaller as createCallerFacts } from "./facts.js";
|
import { facts, createCaller as createCallerFacts } from "./facts.js";
|
||||||
import { createCaller as createCallerMessages } from "./messages.js";
|
import { createCaller as createCallerMessages } from "./messages.js";
|
||||||
import { createCaller as createCallerFactTriggers } from "./fact-triggers.js";
|
import { createCaller as createCallerFactTriggers } from "./fact-triggers.js";
|
||||||
|
import { factTriggers } from "./fact-triggers.js";
|
||||||
import { openrouter } from "./provider.js";
|
import { openrouter } from "./provider.js";
|
||||||
|
|
||||||
const factsCaller = createCallerFacts({});
|
const factsCaller = createCallerFacts({});
|
||||||
@@ -42,6 +43,7 @@ export const chat = router({
|
|||||||
conversations,
|
conversations,
|
||||||
messages,
|
messages,
|
||||||
facts,
|
facts,
|
||||||
|
factTriggers,
|
||||||
sendMessage: publicProcedure
|
sendMessage: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
(x) =>
|
(x) =>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const useStore = create<Store>()(
|
|||||||
systemPrompt: defaultSystemPrompt,
|
systemPrompt: defaultSystemPrompt,
|
||||||
parameters: defaultParameters,
|
parameters: defaultParameters,
|
||||||
facts: [],
|
facts: [],
|
||||||
|
factTriggers: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
setConversationId: (conversationId) =>
|
setConversationId: (conversationId) =>
|
||||||
set((stateDraft) => {
|
set((stateDraft) => {
|
||||||
@@ -69,6 +70,10 @@ export const useStore = create<Store>()(
|
|||||||
set((stateDraft) => {
|
set((stateDraft) => {
|
||||||
stateDraft.facts = facts;
|
stateDraft.facts = facts;
|
||||||
}),
|
}),
|
||||||
|
setFactTriggers: (factTriggers) =>
|
||||||
|
set((stateDraft) => {
|
||||||
|
stateDraft.factTriggers = factTriggers;
|
||||||
|
}),
|
||||||
removeFact: (factId) =>
|
removeFact: (factId) =>
|
||||||
set((stateDraft) => {
|
set((stateDraft) => {
|
||||||
stateDraft.facts.splice(
|
stateDraft.facts.splice(
|
||||||
@@ -76,6 +81,13 @@ export const useStore = create<Store>()(
|
|||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
removeFactTrigger: (factTriggerId) =>
|
||||||
|
set((stateDraft) => {
|
||||||
|
stateDraft.factTriggers.splice(
|
||||||
|
stateDraft.factTriggers.findIndex((ft) => ft.id === factTriggerId),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}),
|
||||||
setLoading: (loading) =>
|
setLoading: (loading) =>
|
||||||
set((stateDraft) => {
|
set((stateDraft) => {
|
||||||
stateDraft.loading = loading;
|
stateDraft.loading = loading;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { Message as UIMessage } from "ai";
|
import type { Message as UIMessage } from "ai";
|
||||||
import type { generateText } from "ai";
|
import type { generateText } from "ai";
|
||||||
import type { Conversation, Fact } from "./database/lowdb.js";
|
import type { Conversation, Fact, FactTrigger } from "./database/lowdb.js";
|
||||||
|
|
||||||
export type OtherParameters = Omit<
|
export type OtherParameters = Omit<
|
||||||
Parameters<typeof generateText>[0],
|
Parameters<typeof generateText>[0],
|
||||||
@@ -19,6 +19,7 @@ export type Store = {
|
|||||||
systemPrompt: string;
|
systemPrompt: string;
|
||||||
parameters: OtherParameters;
|
parameters: OtherParameters;
|
||||||
facts: Array<Fact>;
|
facts: Array<Fact>;
|
||||||
|
factTriggers: Array<FactTrigger>;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
setConversationId: (conversationId: string) => void;
|
setConversationId: (conversationId: string) => void;
|
||||||
setConversationTitle: (conversationTitle: string) => void;
|
setConversationTitle: (conversationTitle: string) => void;
|
||||||
@@ -30,7 +31,9 @@ export type Store = {
|
|||||||
setSystemPrompt: (systemPrompt: string) => void;
|
setSystemPrompt: (systemPrompt: string) => void;
|
||||||
setParameters: (parameters: OtherParameters) => void;
|
setParameters: (parameters: OtherParameters) => void;
|
||||||
setFacts: (facts: Array<Fact>) => void;
|
setFacts: (facts: Array<Fact>) => void;
|
||||||
|
setFactTriggers: (factTriggers: Array<FactTrigger>) => void;
|
||||||
removeFact: (factId: string) => void;
|
removeFact: (factId: string) => void;
|
||||||
|
removeFactTrigger: (factTriggerId: string) => void;
|
||||||
setLoading: (loading: boolean) => void;
|
setLoading: (loading: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user