Source code

Revision control

Copy as Markdown

Other Tools

/*
This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// Every time the schema or the underlying data changes, you must bump up the
// schema version.
// Remember to:
// 1. Bump up the version number
// 2. Add a migration function to migrate the data to the new schema.
// 3. Update #createDatabaseEntities and #checkDatabaseHealth
// 4. Add a test to check that the migration works correctly.
// Note: migrations should be reasonably re-entry-friendly. If the user
// downgrades, the schema version is decreased, and upon a subsequent upgrade,
// the migration step is reapplied.
// This ensures that any necessary conversions are performed, even for entries
// added after the downgrade.
// In practice, schema changes should be additive, allowing newer versions to
// operate on older schemas, albeit with potentially reduced functionality.
export const ESCAPE_CHAR = "/";
export const CONVERSATION_TABLE = `
CREATE TABLE conversation (
conv_id TEXT PRIMARY KEY,
title TEXT,
description TEXT,
page_url TEXT,
page_meta_jsonb BLOB,
created_date INTEGER NOT NULL,
updated_date INTEGER NOT NULL,
status INTEGER NOT NULL DEFAULT 0,
active_branch_tip_message_id TEXT -- no foreign here, as we insert messages later.
) WITHOUT ROWID;
`;
export const CONVERSATION_UPDATED_DATE_INDEX = `
CREATE INDEX conversation_updated_date_idx ON conversation(updated_date);
`;
export const MESSAGE_TABLE = `
CREATE TABLE message (
message_id TEXT PRIMARY KEY,
conv_id TEXT NOT NULL REFERENCES conversation(conv_id) ON DELETE CASCADE,
created_date INTEGER NOT NULL,
parent_message_id TEXT REFERENCES message(message_id) ON DELETE CASCADE,
revision_root_message_id TEXT REFERENCES message(message_id) ON DELETE CASCADE,
ordinal INTEGER NOT NULL CHECK(ordinal >= 0),
is_active_branch INTEGER NOT NULL,
role INTEGER NOT NULL,
model_id TEXT,
params_jsonb BLOB,
content_jsonb BLOB,
usage_jsonb BLOB,
page_url TEXT,
turn_index INTEGER,
insights_enabled BOOLEAN,
insights_flag_source INTEGER,
insights_applied_jsonb BLOB,
web_search_queries_jsonb BLOB
) WITHOUT ROWID;
`;
export const MESSAGE_ORDINAL_INDEX = `
CREATE INDEX message_ordinal_idx ON message(ordinal);
`;
// @todo Bug 2005423
// Maybe add hashed url column to optimize message_url_idx
export const MESSAGE_URL_INDEX = `
CREATE INDEX message_url_idx ON message(page_url);
`;
export const MESSAGE_CREATED_DATE_INDEX = `
CREATE INDEX message_created_date_idx ON message(created_date);
`;
export const MESSAGE_CONV_ID_INDEX = `
CREATE INDEX IF NOT EXISTS message_conv_id_idx ON message(conv_id);
`;
export const CONVERSATION_INSERT = `
INSERT INTO conversation (
conv_id, title, description, page_url, page_meta_jsonb,
created_date, updated_date, status, active_branch_tip_message_id
) VALUES (
:conv_id, :title, :description, :page_url, jsonb(:page_meta),
:created_date, :updated_date, :status, :active_branch_tip_message_id
)
ON CONFLICT(conv_id) DO UPDATE
SET title = :title,
updated_date = :updated_date,
status = :status,
active_branch_tip_message_id = :active_branch_tip_message_id;
`;
export const MESSAGE_INSERT = `
INSERT INTO message (
message_id, conv_id, created_date, parent_message_id,
revision_root_message_id, ordinal, is_active_branch, role,
model_id, params_jsonb, content_jsonb, usage_jsonb, page_url, turn_index,
insights_enabled, insights_flag_source, insights_applied_jsonb,
web_search_queries_jsonb
) VALUES (
:message_id, :conv_id, :created_date, :parent_message_id,
:revision_root_message_id, :ordinal, :is_active_branch, :role,
:model_id, jsonb(:params), jsonb(:content), jsonb(:usage), :page_url, :turn_index,
:insights_enabled, :insights_flag_source, jsonb(:insights_applied_jsonb),
jsonb(:web_search_queries_jsonb)
)
ON CONFLICT(message_id) DO UPDATE SET
is_active_branch = :is_active_branch;
`;
export const CONVERSATIONS_MOST_RECENT = `
SELECT conv_id, title
FROM conversation
ORDER BY updated_date DESC
LIMIT :limit;
`;
export const CONVERSATIONS_OLDEST = `
SELECT conv_id, title
FROM conversation
ORDER BY updated_date ASC
LIMIT :limit;
`;
export const CONVERSATION_BY_ID = `
SELECT conv_id, title, description, page_url,
json(page_meta_jsonb) AS page_meta, created_date, updated_date,
status, active_branch_tip_message_id
FROM conversation WHERE conv_id = :conv_id;
`;
export const CONVERSATIONS_BY_DATE = `
SELECT conv_id, title, description, page_url,
json(page_meta_jsonb) AS page_meta, created_date, updated_date,
status, active_branch_tip_message_id
FROM conversation
WHERE updated_date >= :start_date AND updated_date <= :end_date
ORDER BY updated_date DESC;
`;
export const CONVERSATIONS_BY_URL = `
SELECT c.conv_id, c.title, c.description, c.page_url,
json(c.page_meta_jsonb) AS page_meta, c.created_date, c.updated_date,
c.status, c.active_branch_tip_message_id
FROM conversation c
WHERE EXISTS (
SELECT 1
FROM message m
WHERE m.conv_id = c.conv_id
AND m.page_url = :page_url
)
ORDER BY c.updated_date DESC;
`;
/**
* Get all messages for multiple conversations
*
* @param {number} amount - The number of conversation IDs to get messages for
*/
export function getConversationMessagesSql(amount) {
return `
SELECT
message_id, created_date, parent_message_id, revision_root_message_id,
ordinal, is_active_branch, role, model_id, conv_id,
json(params_jsonb) AS params, json(usage_jsonb) AS usage,
page_url, turn_index, insights_enabled, insights_flag_source,
json(insights_applied_jsonb) AS insights_applied,
json(web_search_queries_jsonb) AS web_search_queries,
json(content_jsonb) AS content
FROM message
WHERE conv_id IN(${new Array(amount).fill("?").join(",")})
ORDER BY ordinal ASC;
`;
}
export const CONVERSATIONS_CONTENT_SEARCH = `
SELECT c.conv_id, c.title, c.description, c.page_url,
json(c.page_meta_jsonb) AS page_meta, c.created_date, c.updated_date,
c.status, c.active_branch_tip_message_id
FROM conversation c
JOIN message m ON m.conv_id = c.conv_id
WHERE json_type(m.content_jsonb, :path) IS NOT NULL;
`;
export const CONVERSATIONS_CONTENT_SEARCH_BY_ROLE = `
SELECT c.conv_id, c.title, c.description, c.page_url,
json(c.page_meta_jsonb) AS page_meta, c.created_date, c.updated_date,
c.status, c.active_branch_tip_message_id
FROM conversation c
JOIN message m ON m.conv_id = c.conv_id
WHERE m.role = :role
AND json_type(m.content_jsonb, :path) IS NOT NULL;
`;
export const CONVERSATIONS_HISTORY_SEARCH = `
SELECT c.conv_id, c.title, c.description, c.page_url,
json(c.page_meta_jsonb) AS page_meta, c.created_date, c.updated_date,
c.status, c.active_branch_tip_message_id
FROM conversation c
JOIN message m ON m.conv_id = c.conv_id
WHERE m.role = 0
AND (
CAST(json_extract(m.content_jsonb, :path) AS TEXT) LIKE :pattern ESCAPE '/'
OR
c.title LIKE :pattern ESCAPE '/'
);
`;
export const MESSAGES_BY_DATE = `
SELECT
message_id, created_date, parent_message_id, revision_root_message_id,
ordinal, is_active_branch, role, model_id, conv_id,
json(params_jsonb) AS params, json(usage_jsonb) AS usage,
page_url, turn_index, insights_enabled, insights_flag_source,
json(insights_applied_jsonb) AS insights_applied,
json(web_search_queries_jsonb) AS web_search_queries,
json(content_jsonb) AS content
FROM message
WHERE created_date >= :start_date AND created_date <= :end_date
ORDER BY created_date DESC
LIMIT :limit OFFSET :offset;
`;
export const MESSAGES_BY_DATE_AND_ROLE = `
SELECT
message_id, created_date, parent_message_id, revision_root_message_id,
ordinal, is_active_branch, role, model_id, conv_id,
json(params_jsonb) AS params, json(usage_jsonb) AS usage,
page_url, turn_index, insights_enabled, insights_flag_source,
json(insights_applied_jsonb) AS insights_applied,
json(web_search_queries_jsonb) AS web_search_queries,
json(content_jsonb) AS content
FROM message
WHERE role = :role
AND created_date >= :start_date AND created_date <= :end_date
ORDER BY created_date DESC
LIMIT :limit OFFSET :offset;
`;
export const DELETE_CONVERSATION_BY_ID = `
DELETE FROM conversation WHERE conv_id = :conv_id;
`;
export const CONVERSATION_HISTORY = `
SELECT c.conv_id, c.title, c.created_date, c.updated_date, (
SELECT group_concat(t.page_url)
FROM (
SELECT
m.page_url
FROM message m
WHERE m.conv_id = c.conv_id
AND m.page_url IS NOT NULL
GROUP BY m.page_url
ORDER BY MAX(m.created_date) ASC
) AS t
) AS urls
FROM conversation c
WHERE EXISTS (
SELECT 1
FROM message AS m
WHERE m.conv_id = c.conv_id
)
ORDER BY c.updated_date {sort}
LIMIT :limit OFFSET :offset;
`;