Skip to content
Closed
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
7 changes: 5 additions & 2 deletions apps/browser-extension/entrypoints/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,12 @@ export default defineBackground(() => {
const response = responseData as {
results?: Array<{ memory?: string }>
}
// Return raw memory strings; consumers handle numbering/formatting.
const memories: string[] = []
response.results?.forEach((result, index) => {
memories.push(`${index + 1}. ${result.memory} \n`)
response.results?.forEach((result) => {
if (result.memory) {
memories.push(result.memory)
}
})
console.log("Memories:", memories)
await trackEvent(eventSource)
Expand Down
177 changes: 17 additions & 160 deletions apps/browser-extension/entrypoints/content/chatgpt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import {
autoSearchEnabled,
autoCapturePromptsEnabled,
} from "../../utils/storage"
import {
buildPromptInjection,
createIncludedMemoriesPopup,
serializeMemories,
} from "../../utils/included-memories"
import {
createChatGPTInputBarElement,
DOMUtils,
Expand Down Expand Up @@ -156,16 +161,21 @@ async function getRelatedMemoriesForChatGPT(actionSource: string) {
timeoutPromise,
])

if (response?.success && response?.data) {
if (
response?.success &&
Array.isArray(response.data) &&
response.data.length > 0
) {
const memories = response.data as string[]
const promptElement = document.getElementById("prompt-textarea")
if (promptElement) {
promptElement.dataset.supermemories = `\n\nSupermemories of user (only for the reference): ${response.data}`
promptElement.dataset.supermemories = buildPromptInjection(memories)
console.log(
"Prompt element dataset:",
promptElement.dataset.supermemories,
)

iconElement.dataset.memoriesData = response.data
iconElement.dataset.memoriesData = serializeMemories(memories)

updateChatGPTIconFeedback("Included Memories", iconElement)
} else {
Expand Down Expand Up @@ -325,105 +335,11 @@ function updateChatGPTIconFeedback(
`

if (message === "Included Memories" && iconElement.dataset.memoriesData) {
const popup = document.createElement("div")
popup.style.cssText = `
position: fixed;
bottom: 80px;
left: 50%;
transform: translateX(-50%);
background: #1a1a1a;
color: white;
padding: 0;
border-radius: 12px;
font-size: 13px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
max-width: 500px;
max-height: 400px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
z-index: 999999;
display: none;
border: 1px solid #333;
`

const header = document.createElement("div")
header.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px;
border-bottom: 1px solid #333;
opacity: 0.8;
`
header.innerHTML = `
<span style="font-weight: 600; color: #fff;">Included Memories</span>
`

const content = document.createElement("div")
content.style.cssText = `
padding: 0;
max-height: 300px;
overflow-y: auto;
`

const memoriesText = iconElement.dataset.memoriesData || ""
console.log("Memories text:", memoriesText)
const individualMemories = memoriesText
.split(/[,\n]/)
.map((memory) => memory.trim())
.filter((memory) => memory.length > 0 && memory !== ",")
console.log("Individual memories:", individualMemories)

individualMemories.forEach((memory, index) => {
const memoryItem = document.createElement("div")
memoryItem.style.cssText = `
display: flex;
align-items: center;
gap: 6px;
padding: 10px;
font-size: 13px;
line-height: 1.4;
`

const memoryText = document.createElement("div")
memoryText.style.cssText = `
flex: 1;
color: #e5e5e5;
`
memoryText.textContent = memory.trim()

const removeBtn = document.createElement("button")
removeBtn.style.cssText = `
background: transparent;
color: #9ca3af;
border: none;
padding: 4px;
border-radius: 4px;
cursor: pointer;
flex-shrink: 0;
height: fit-content;
display: flex;
align-items: center;
justify-content: center;
`
removeBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>`
removeBtn.dataset.memoryIndex = index.toString()

removeBtn.addEventListener("mouseenter", () => {
removeBtn.style.color = "#ef4444"
})
removeBtn.addEventListener("mouseleave", () => {
removeBtn.style.color = "#9ca3af"
})

memoryItem.appendChild(memoryText)
memoryItem.appendChild(removeBtn)
content.appendChild(memoryItem)
const popupHandle = createIncludedMemoriesPopup({
iconElement,
getPromptElement: () => document.getElementById("prompt-textarea"),
})

popup.appendChild(header)
popup.appendChild(content)
document.body.appendChild(popup)

feedbackDiv.addEventListener("mouseenter", () => {
const textSpan = feedbackDiv.querySelector("span:last-child")
if (textSpan) {
Expand All @@ -440,67 +356,8 @@ function updateChatGPTIconFeedback(

feedbackDiv.addEventListener("click", (e) => {
e.stopPropagation()
popup.style.display = "block"
})

document.addEventListener("click", (e) => {
if (!popup.contains(e.target as Node)) {
popup.style.display = "none"
}
})

content.querySelectorAll("button[data-memory-index]").forEach((button) => {
const htmlButton = button as HTMLButtonElement
htmlButton.addEventListener("click", () => {
const index = Number.parseInt(htmlButton.dataset.memoryIndex || "0", 10)
const memoryItem = htmlButton.parentElement

if (memoryItem) {
content.removeChild(memoryItem)
}

const currentMemories = (iconElement.dataset.memoriesData || "")
.split(/[,\n]/)
.map((memory) => memory.trim())
.filter((memory) => memory.length > 0 && memory !== ",")
currentMemories.splice(index, 1)

const updatedMemories = currentMemories.join(" ,")

iconElement.dataset.memoriesData = updatedMemories

const promptElement = document.getElementById("prompt-textarea")
if (promptElement) {
promptElement.dataset.supermemories = `\n\nSupermemories of user (only for the reference): ${updatedMemories}`
}

content
.querySelectorAll("button[data-memory-index]")
.forEach((btn, newIndex) => {
const htmlBtn = btn as HTMLButtonElement
htmlBtn.dataset.memoryIndex = newIndex.toString()
})

if (currentMemories.length <= 1) {
if (promptElement?.dataset.supermemories) {
delete promptElement.dataset.supermemories
delete iconElement.dataset.memoriesData
iconElement.innerHTML = iconElement.dataset.originalHtml || ""
delete iconElement.dataset.originalHtml
}
popup.style.display = "none"
if (document.body.contains(popup)) {
document.body.removeChild(popup)
}
}
})
popupHandle.show()
})

setTimeout(() => {
if (document.body.contains(popup)) {
document.body.removeChild(popup)
}
}, 300000)
}

iconElement.innerHTML = ""
Expand Down
Loading
Loading