Skip to content
Draft
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
21 changes: 21 additions & 0 deletions public/elements/tind-refs.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"

export default function TindRefs () {
return (
<Accordion type="single" collapsible className="w-full">
<AccordionItem value="ref-1">
<AccordionTrigger>Metadata</AccordionTrigger>
<AccordionContent>
<p className="mb-2" style={{ whiteSpace: 'pre-line' }}>
{props.tind_message || 'no references supplied'}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there an option to not return a References section at all unless props.tind_message is present?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how are links rendered in this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anarchivist The way that the custom element is called in chatbot/app.py, it should only render the element if a message from langchain has a metadata['tind_message']. Or, after the proposed changes upstream, the element in the data layer should be able to restore it from props.

Once that's changed upstream we may need to alter our chatbot or graph_manager code to make sure the tind_messages are still getting filtered out of the context sent/returned to/from the summarizer.

All that being said, I think the custom_element part of this approach allows us to get a little more specific about how we customize the output of the references. With structured responses or even some advanced string parsing we could add UI signposting like reference counts or links to specific pages in the source documents.

</p>
</AccordionContent>
</AccordionItem>
</Accordion>
)
}
30 changes: 28 additions & 2 deletions willa/web/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ async def ocs() -> None:
async def on_chat_resume(thread: ThreadDict) -> None:
"""Resume chat session for data persistence."""
await cl.context.emitter.set_commands(COMMANDS)

# recreate custom elements from metadata
# results in a duplicate message in data layer!!
# for msg in thread['steps']:
# if 'tind_message' in msg['metadata']:
# tind_refs = cl.CustomElement(name='tind-refs', props=msg['metadata'])
# await cl.Message(
# author='TIND',
# content='References:',
# elements=[tind_refs],
# metadata=msg['metadata']
# ).send()
# pylint: enable="unused-argument"


Expand Down Expand Up @@ -89,8 +101,22 @@ async def chat(message: cl.Message) -> None:
await cl.Message(content=reply['ai_message']).send()

if 'tind_message' in reply:
await cl.Message(author='TIND',
content=reply['tind_message']).send()
tind_refs = cl.CustomElement(
name='tind-refs',
props={'tind_message': reply['tind_message']}
)
msg = cl.Message(
author='TIND',
content='References:',
elements=[tind_refs],
metadata={'tind_message': reply['tind_message']}
)
await msg.send()

# print(f"Message ID: {msg.id}")
# print(f"Elements: {msg.elements}")
# print(f"Thread ID: {message.thread_id}")
# print(f"msg: {msg}")

if 'no_results' in reply:
await cl.Message(author='System', type='system_message',
Expand Down