Skip to content

Commit

Permalink
prettier formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
mruwnik committed Oct 3, 2023
1 parent ac25ce7 commit 23c01d4
Show file tree
Hide file tree
Showing 17 changed files with 810 additions and 718 deletions.
18 changes: 10 additions & 8 deletions web/src/components/assistant.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {useState} from 'react'
import {ShowCitation, CitationsBlock} from './citations'
import {GlossarySpan} from './glossary'
import type {Citation, AssistantEntry as AssistantType} from '../types'
import { useState } from "react";
import { ShowCitation, CitationsBlock } from "./citations";
import { GlossarySpan } from "./glossary";
import type { Citation, AssistantEntry as AssistantType } from "../types";

export const AssistantEntry: React.FC<{entry: AssistantType}> = ({entry}) => {
export const AssistantEntry: React.FC<{ entry: AssistantType }> = ({
entry,
}) => {
return (
<div className="mt-3 mb-8">
{entry.content.split('\n').map((paragraph, i) => (
{entry.content.split("\n").map((paragraph, i) => (
<CitationsBlock
key={i}
text={paragraph}
Expand All @@ -25,5 +27,5 @@ export const AssistantEntry: React.FC<{entry: AssistantType}> = ({entry}) => {
}
</ul>
</div>
)
}
);
};
179 changes: 95 additions & 84 deletions web/src/components/chat.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useState, useEffect} from 'react'
import {queryLLM, getStampyContent, runSearch} from '../hooks/useSearch'
import { useState, useEffect } from "react";
import { queryLLM, getStampyContent, runSearch } from "../hooks/useSearch";

import type {
CurrentSearch,
Expand All @@ -8,147 +8,158 @@ import type {
AssistantEntry as AssistantEntryType,
LLMSettings,
Followup,
} from '../types'
import {SearchBox} from '../components/searchbox'
import {AssistantEntry} from '../components/assistant'
import {Entry as EntryTag} from '../components/entry'
} from "../types";
import { SearchBox } from "../components/searchbox";
import { AssistantEntry } from "../components/assistant";
import { Entry as EntryTag } from "../components/entry";

const MAX_FOLLOWUPS = 4
const MAX_FOLLOWUPS = 4;

type State =
| {
state: 'idle'
state: "idle";
}
| {
state: 'loading'
phase: 'semantic' | 'prompt' | 'llm'
citations: Citation[]
state: "loading";
phase: "semantic" | "prompt" | "llm";
citations: Citation[];
}
| {
state: 'streaming'
response: AssistantEntryType
}
state: "streaming";
response: AssistantEntryType;
};

// smooth-scroll to the bottom of the window if we're already less than 30% a screen away
// note: finicky interaction with "smooth" - maybe fix later.
function scroll30() {
if (document.documentElement.scrollHeight - window.scrollY > window.innerHeight * 1.3) return
window.scrollTo({top: document.body.scrollHeight, behavior: 'smooth'})
if (
document.documentElement.scrollHeight - window.scrollY >
window.innerHeight * 1.3
)
return;
window.scrollTo({ top: document.body.scrollHeight, behavior: "smooth" });
}

type ChatParams = {
sessionId: string
settings: LLMSettings
onQuery?: (q: string) => any
onNewEntry?: (history: Entry[]) => any
}
sessionId: string;
settings: LLMSettings;
onQuery?: (q: string) => any;
onNewEntry?: (history: Entry[]) => any;
};

const Chat = ({sessionId, settings, onQuery, onNewEntry}: ChatParams) => {
const [entries, setEntries] = useState<Entry[]>([])
const [current, setCurrent] = useState<CurrentSearch>()
const [citations, setCitations] = useState<Citation[]>([])
const Chat = ({ sessionId, settings, onQuery, onNewEntry }: ChatParams) => {
const [entries, setEntries] = useState<Entry[]>([]);
const [current, setCurrent] = useState<CurrentSearch>();
const [citations, setCitations] = useState<Citation[]>([]);

const updateCurrent = (current: CurrentSearch) => {
setCurrent(current)
if (current?.phase === 'streaming') {
scroll30()
setCurrent(current);
if (current?.phase === "streaming") {
scroll30();
}
}
};

const updateCitations = (allCitations: Citation[], current?: CurrentSearch) => {
if (!current) return
const updateCitations = (
allCitations: Citation[],
current?: CurrentSearch
) => {
if (!current) return;

const entryCitations = Array.from(current.citationsMap.values())
const entryCitations = Array.from(current.citationsMap.values());
if (!entryCitations.some((c) => !c.index)) {
// All of the entries citations have indexes, so there weren't any changes since the last check
return
return;
}

// Get a mapping of all known citations, so as to reuse them if they appear again
const citationsMapping = Object.fromEntries(allCitations.map((c) => [c.title + c.url, c.index]))
const citationsMapping = Object.fromEntries(
allCitations.map((c) => [c.title + c.url, c.index])
);

entryCitations.forEach((c) => {
const hash = c.title + c.url
const index = citationsMapping[hash]
const hash = c.title + c.url;
const index = citationsMapping[hash];
if (!index) {
c.index = allCitations.length + 1
allCitations.push(c)
c.index = allCitations.length + 1;
allCitations.push(c);
} else {
c.index = index
c.index = index;
}
})
setCitations(allCitations)
setCurrent(current)
}
});
setCitations(allCitations);
setCurrent(current);
};

const addEntry = (entry: Entry) => {
setEntries((prev) => {
const entries = [...prev, entry]
const entries = [...prev, entry];
if (onNewEntry) {
onNewEntry(entries)
onNewEntry(entries);
}
return entries
})
}
return entries;
});
};

const search = async (
query: string,
query_source: 'search' | 'followups',
query_source: "search" | "followups",
enable: (f_set: Followup[] | ((fs: Followup[]) => Followup[])) => void,
controller: AbortController
) => {
// clear the query box, append to entries
const userEntry: Entry = {
role: 'user',
content: query_source === 'search' ? query : query.split('\n', 2)[1]!,
}
role: "user",
content: query_source === "search" ? query : query.split("\n", 2)[1]!,
};

const {result, followups} = await runSearch(
const { result, followups } = await runSearch(
query,
query_source,
settings,
entries,
updateCurrent,
sessionId,
controller
)
if (result.content !== 'aborted') {
addEntry(userEntry)
addEntry(result)
enable(followups || [])
scroll30()
);
if (result.content !== "aborted") {
addEntry(userEntry);
addEntry(result);
enable(followups || []);
scroll30();
} else {
enable([])
enable([]);
}
setCurrent(undefined)
}
setCurrent(undefined);
};

var last_entry = <></>
var last_entry = <></>;
switch (current?.phase) {
case 'semantic':
last_entry = <p>Loading: Performing semantic search...</p>
break
case 'prompt':
last_entry = <p>Loading: Creating prompt...</p>
break
case 'llm':
last_entry = <p>Loading: Waiting for LLM...</p>
break
case 'streaming':
updateCitations(citations, current)
last_entry = <AssistantEntry entry={current} />
break
case 'followups':
case "semantic":
last_entry = <p>Loading: Performing semantic search...</p>;
break;
case "prompt":
last_entry = <p>Loading: Creating prompt...</p>;
break;
case "llm":
last_entry = <p>Loading: Waiting for LLM...</p>;
break;
case "streaming":
updateCitations(citations, current);
last_entry = <AssistantEntry entry={current} />;
break;
case "followups":
last_entry = (
<>
<AssistantEntry entry={current} />
<p>Checking for followups...</p>
</>
)
break
);
break;
default:
last_entry = <button onClick={() => setEntries([])}>Clear history</button>
break
last_entry = (
<button onClick={() => setEntries([])}>Clear history</button>
);
break;
}

return (
Expand All @@ -160,7 +171,7 @@ const Chat = ({sessionId, settings, onQuery, onNewEntry}: ChatParams) => {

{last_entry}
</ul>
)
}
);
};

export default Chat
export default Chat;
Loading

0 comments on commit 23c01d4

Please sign in to comment.