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
1 change: 0 additions & 1 deletion apps/browser-extension/entrypoints/content/chatgpt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ function addSupermemoryButtonToMemoriesDialog() {

if (memoriesDialog.querySelector("#supermemory-save-button")) return


const deleteAllContainer = memoriesDialog.querySelector(
".flex.items-center.gap-0\\.5",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ELEMENT_IDS, MESSAGE_TYPES, UI_CONFIG } from "../../utils/constants"
let currentQuery = ""
let fabElement: HTMLElement | null = null
let panelElement: HTMLElement | null = null
let selectedResults: Set<number> = new Set()
const selectedResults: Set<number> = new Set()

/**
* Get the selection rectangle for positioning the FAB
Expand Down
5 changes: 4 additions & 1 deletion apps/browser-extension/entrypoints/content/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ export function setupStorageListener() {
}

try {
await Promise.all([bearerToken.setValue(token), userData.setValue(user)])
await Promise.all([
bearerToken.setValue(token),
userData.setValue(user),
])
} catch {
// Do nothing
}
Expand Down
21 changes: 12 additions & 9 deletions apps/browser-extension/entrypoints/content/twitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,17 +257,20 @@ async function showOnboardingToast() {
const icon = document.createElement("img")
icon.src = iconUrl
icon.alt = "Supermemory"
icon.style.cssText = "width: 24px; height: 24px; border-radius: 4px; flex-shrink: 0; margin-top: 2px;"
icon.style.cssText =
"width: 24px; height: 24px; border-radius: 4px; flex-shrink: 0; margin-top: 2px;"

const textContainer = document.createElement("div")
textContainer.style.cssText = "display: flex; flex-direction: column; gap: 4px; flex: 1;"
textContainer.style.cssText =
"display: flex; flex-direction: column; gap: 4px; flex: 1;"

const title = document.createElement("span")
title.style.cssText = "font-weight: 600; font-size: 14px; color: #111827;"
title.textContent = "Import X/Twitter Bookmarks"

const description = document.createElement("span")
description.style.cssText = "font-size: 13px; color: #6b7280; line-height: 1.4;"
description.style.cssText =
"font-size: 13px; color: #6b7280; line-height: 1.4;"
description.textContent =
"You can import all your Twitter bookmarks to Supermemory with one click."

Expand Down Expand Up @@ -362,10 +365,7 @@ async function showOnboardingToast() {
learnMoreButton.style.backgroundColor = "transparent"
})
learnMoreButton.addEventListener("click", () => {
window.open(
"https://docs.supermemory.ai/connectors/twitter",
"_blank",
)
window.open("https://docs.supermemory.ai/connectors/twitter", "_blank")
})

buttonsContainer.appendChild(importButton)
Expand All @@ -377,7 +377,10 @@ async function showOnboardingToast() {
progressBarContainer.setAttribute("aria-valuemin", "0")
progressBarContainer.setAttribute("aria-valuemax", "100")
progressBarContainer.setAttribute("aria-valuenow", "0")
progressBarContainer.setAttribute("aria-label", "Onboarding toast auto-dismiss progress")
progressBarContainer.setAttribute(
"aria-label",
"Onboarding toast auto-dismiss progress",
)
progressBarContainer.style.cssText = `
position: absolute;
bottom: 0;
Expand All @@ -394,7 +397,7 @@ async function showOnboardingToast() {
transform-origin: left;
animation: smProgressGrow ${duration}ms linear forwards;
`

// Update progress bar ARIA value as animation progresses
const startTime = Date.now()
const updateProgress = () => {
Expand Down
5 changes: 4 additions & 1 deletion apps/browser-extension/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ export async function validateAuthToken(): Promise<boolean> {
/**
* Get user data from storage
*/
export async function getUserData(): Promise<{ email?: string; name?: string } | null> {
export async function getUserData(): Promise<{
email?: string
name?: string
} | null> {
try {
return (await userData.getValue()) || null
} catch (error) {
Expand Down
3 changes: 2 additions & 1 deletion apps/browser-extension/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ export const ELEMENT_IDS = {
*/
export const STORAGE_KEYS = {
TWITTER_BOOKMARKS_ONBOARDING_SEEN: "sm_twitter_bookmarks_onboarding_seen",
TWITTER_BOOKMARKS_IMPORT_INTENT_UNTIL: "sm_twitter_bookmarks_import_intent_until",
TWITTER_BOOKMARKS_IMPORT_INTENT_UNTIL:
"sm_twitter_bookmarks_import_intent_until",
} as const

/**
Expand Down
3 changes: 1 addition & 2 deletions apps/browser-extension/utils/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Centralized storage layer using WXT's built-in storage API
*/

import { storage } from '#imports';
import { storage } from "#imports"
import type { Project } from "./types"

/**
Expand Down Expand Up @@ -118,4 +118,3 @@ export async function getTokensLogged(): Promise<boolean> {
export async function setTokensLogged(): Promise<void> {
await tokensLogged.setValue(true)
}

66 changes: 53 additions & 13 deletions apps/docs/integrations/pipecat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ You can obtain an API key from [console.supermemory.ai](https://console.supermem
Supermemory integration is provided through the `SupermemoryPipecatService` class in Pipecat:

```python
from supermemory_pipecat import SupermemoryPipecatService, InputParams
from supermemory_pipecat import SupermemoryPipecatService
from supermemory_pipecat.service import InputParams

memory = SupermemoryPipecatService(
api_key=os.getenv("SUPERMEMORY_API_KEY"),
Expand Down Expand Up @@ -78,11 +79,11 @@ Retrieved memories are formatted and injected into the LLM context before genera

## Memory Modes

| Mode | Static Profile | Dynamic Profile | Search Results | Use Case |
|------|----------------|-----------------|----------------|----------|
| `"profile"` | Yes | Yes | No | Personalization without search |
| `"query"` | No | No | Yes | Finding relevant past context |
| `"full"` | Yes | Yes | Yes | Complete memory (default) |
| Mode | Static Profile | Dynamic Profile | Search Results | Use Case |
| ----------- | -------------- | --------------- | -------------- | ------------------------------ |
| `"profile"` | Yes | Yes | No | Personalization without search |
| `"query"` | No | No | Yes | Finding relevant past context |
| `"full"` | Yes | Yes | Yes | Complete memory (default) |

## Configuration Options

Expand All @@ -96,15 +97,41 @@ InputParams(
search_limit=10, # Max memories to retrieve (default: 10)
search_threshold=0.1, # Similarity threshold 0.0-1.0 (default: 0.1)
system_prompt="Based on previous conversations:\n\n",
inject_mode="auto", # "auto" | "system" | "user"
)
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `search_limit` | int | 10 | Maximum number of memories to retrieve per query |
| `search_threshold` | float | 0.1 | Minimum similarity threshold for memory retrieval |
| `mode` | str | "full" | Memory retrieval mode: `"profile"`, `"query"`, or `"full"` |
| `system_prompt` | str | "Based on previous conversations:\n\n" | Prefix text for memory context |
| Parameter | Type | Default | Description |
| ------------------ | ----- | -------------------------------------- | ------------------------------------------------------------ |
| `search_limit` | int | 10 | Maximum number of memories to retrieve per query |
| `search_threshold` | float | 0.1 | Minimum similarity threshold for memory retrieval |
| `mode` | str | "full" | Memory retrieval mode: `"profile"`, `"query"`, or `"full"` |
| `system_prompt` | str | "Based on previous conversations:\n\n" | Prefix text for memory context |
| `inject_mode` | str | "auto" | How memories are injected: `"auto"`, `"system"`, or `"user"` |

## Injection Modes

The `inject_mode` parameter controls how memories are added to the LLM context:

| Mode | Behavior |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"auto"` | **Auto-detects** based on frame types. If audio frames detected → injects to system prompt (speech-to-speech). If only text frames → injects as user message (STT/TTS). |
| `"system"` | Always injects memories into the system prompt |
| `"user"` | Always injects memories as a user message |

## Speech-to-Speech Models (Gemini Live, etc.)

For speech-to-speech models like Gemini Live, the SDK **automatically detects** audio frames and injects memories into the system prompt. No configuration needed:

```python
from supermemory_pipecat import SupermemoryPipecatService

# Auto-detection works out of the box
memory = SupermemoryPipecatService(
api_key=os.getenv("SUPERMEMORY_API_KEY"),
user_id="unique_user_id",
)
```

## Example: Voice Agent with Memory

Expand All @@ -130,7 +157,8 @@ from pipecat.transports.websocket.fastapi import (
FastAPIWebsocketTransport,
)

from supermemory_pipecat import SupermemoryPipecatService, InputParams
from supermemory_pipecat import SupermemoryPipecatService
from supermemory_pipecat.service import InputParams

app = FastAPI()

Expand Down Expand Up @@ -201,3 +229,15 @@ if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
```

## Example: Gemini Live with Memory

For a complete example using Gemini Live speech-to-speech with Supermemory, check out the reference implementation:

<Card
title="Pipecat Memory Example"
icon="github"
href="https://github.com/supermemoryai/pipecat-memory"
>
Full working example with Gemini Live, including frontend and backend code.
</Card>
2 changes: 1 addition & 1 deletion apps/docs/style.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.dark img[src*="openai.svg"],
.dark img[src*="pipecat.svg"],
.dark img[src*="supermemory.svg"] {
filter: invert(1);
filter: invert(1);
}
Loading
Loading