Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/util/db-schema/llm.ts
Views: 687
// NOTE: this is not just OpenAI, but also includes other models that we use1// Mentally, just ignore "openai" and instead focus on "gpt-*" or "codey" or whatever they are called.2// TODO: refactor this, the names of the tables, etc. to be more generic.34import { History } from "@cocalc/util/types/llm";5import { CREATED_BY, ID } from "./crm";6import { SCHEMA as schema } from "./index";7import { LanguageModel } from "./llm-utils";8import { Table } from "./types";910export interface LLMLogEntry {11id: number;12account_id?: string;13analytics_cookie?: string; // at least one of analytics_cookie or account_id will be set14expire?: Date;15history?: History;16input: string;17model?: LanguageModel;18output: string;19path?: string;20project_id?: string;21prompt_tokens: number;22system?: string;23tag?: string; // useful for keeping track of where queries come frome when doing analytics later24time: Date;25total_time_s: number; // how long the request took in s26total_tokens: number;27}2829Table({30name: "openai_chatgpt_log", // historically a wrong name, don't change it31fields: {32id: ID,33time: { type: "timestamp", desc: "When this particular chat happened." },34analytics_cookie: {35title: "Analytics Cookie",36type: "string",37desc: "The analytics cookie for the user that asked this question.",38},39account_id: CREATED_BY,40system: {41title: "System Context",42type: "string",43desc: "System context prompt.",44render: {45type: "markdown",46},47},48input: {49title: "Input",50type: "string",51desc: "Input text that was sent to chatgpt",52render: {53type: "markdown",54},55},56output: {57title: "Output",58type: "string",59desc: "Output text that was returned from chatgpt",60render: {61type: "markdown",62},63},64history: {65title: "History",66type: "array",67pg_type: "JSONB[]",68desc: "Historical context for this thread of discussion",69render: {70type: "json",71},72},73total_tokens: {74type: "integer",75desc: "The total number of tokens involved in this API call.",76},77prompt_tokens: {78type: "integer",79desc: "The number of tokens in the prompt.",80},81total_time_s: {82type: "number",83desc: "Total amount of time the API call took in seconds.",84},85project_id: {86type: "uuid",87render: { type: "project_link" },88},89path: {90type: "string",91},92expire: {93type: "timestamp",94desc: "optional future date, when the entry will be deleted",95},96model: {97type: "string",98},99tag: {100type: "string",101desc: "A string that the client can include that is useful for analytics later",102},103},104rules: {105desc: "Language Model Log",106primary_key: "id",107pg_indexes: ["account_id", "analytics_cookie", "time"],108user_query: {109get: {110pg_where: [{ "account_id = $::UUID": "account_id" }],111fields: {112id: null,113time: null,114account_id: null,115input: null,116system: null,117output: null,118total_tokens: null,119prompt_tokens: null,120total_time_s: null,121project_id: null,122path: null,123history: null,124expire: null,125model: null,126tag: null,127},128},129set: {130// this is so that a user can expire any chats they wanted to have expunged from131// the system completely.132fields: {133account_id: "account_id",134id: true,135expire: true,136},137},138},139},140});141142Table({143name: "crm_openai_chatgpt_log",144rules: {145virtual: "openai_chatgpt_log",146primary_key: "id",147user_query: {148get: {149pg_where: [],150admin: true,151fields: {152id: null,153time: null,154account_id: null,155analytics_cookie: null,156input: null,157system: null,158output: null,159total_tokens: null,160prompt_tokens: null,161total_time_s: null,162project_id: null,163path: null,164history: null,165model: null,166tag: null,167},168},169},170},171fields: schema.openai_chatgpt_log.fields,172});173174export interface EmbeddingData {175id: string; // fragment id, i.e., exactly what is after the # in the url176text?: string; // test that is embedded using a model177meta?: object; // extra metadata178hash?: string; // hash that is used to know when we need to update the point; e.g., hash of text and meta.179}180181// *technical* limit is 8K tokens, but there's no good reason for a search to be really longthere's no good reason for a search to be really long,182// and it could be costly.183export const MAX_SEARCH_TEXT = 4000;184// Limit on the number of outputs when doing a search. This should stay under 10MB total,185// to avoid message size limits. Use paging for more, which app client automatically does.186export const MAX_SEARCH_LIMIT = 200;187188// Maximum number of distinct embeddings that a single client can save at once.189// The app client itself will automatically chunk the saves at this size.190export const MAX_SAVE_LIMIT = 50;191// Similar limit on removing items; can be larger since no vector embedding computation, etc.192export const MAX_REMOVE_LIMIT = 100;193// See https://platform.openai.com/docs/guides/embeddings/what-are-embeddings194export const MAX_EMBEDDINGS_TOKENS = 8191;195196Table({197name: "openai_embedding_log",198fields: {199id: ID,200time: { type: "timestamp", desc: "When this particular chat happened." },201account_id: CREATED_BY,202tokens: {203type: "integer",204desc: "The total number of tokens of the input.",205},206model: {207type: "string",208desc: "The model that was used; if left blank it is assumed to be text-embedding-ada-002.",209},210},211rules: {212desc: "OpenAI Vector Embedding Log. This logs who is responsible for calls to openai. It is used to avoid abuse, have good analytics, and may eventually be used for pay-as-you-go, etc.",213primary_key: "id",214pg_indexes: ["((tokens IS NOT NULL))"],215},216});217218Table({219name: "openai_embedding_cache",220fields: {221input_sha1: {222title: "Sha1 hash of input",223type: "string",224pg_type: "char(40)",225},226vector: {227type: "array",228pg_type: "double precision[]",229desc: "The vector obtained from openai.",230},231model: {232type: "string",233desc: "The model that was used; if left blank it is assumed to be text-embedding-ada-002.",234},235expire: {236type: "timestamp",237desc: "Date when the cache entry will be deleted. Some entries correspond to queries users type, so may be very frequent, or content in shared notebooks (e.g., students in class), so caching is very valuable when it is actively happening. Others don't get accessed, so we free up the space.",238},239},240rules: {241desc: "OpenAI Vector Embedding Cache. This is a cache of embeddings that we computed using openai. It helps us avoid having to recompute embeddings, which costs money and takes time. It is only used as a CACHE by our system. This entire table could be deleted at any time, and the only impact is that some things may be slower and we may have to pay to recompute embeddings, but nothing should *break*.",242primary_key: "input_sha1",243pg_indexes: ["((vector IS NOT NULL))"],244},245});246247248