Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 3,916 Bytes
1778c9e d7cd63b 1778c9e d7cd63b dab40ed 52c6f5c dab40ed 1778c9e d7cd63b 1778c9e d7cd63b 1778c9e d7cd63b 1778c9e dab40ed 1778c9e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
import { idb } from "$lib/remult.js";
import { dequal } from "dequal";
import { Entity, Fields, repo, type MembersOnly } from "remult";
import { PersistedState } from "runed";
import { checkpoints } from "./checkpoints.svelte";
import { conversations } from "./conversations.svelte";
@Entity("project")
export class ProjectEntity {
@Fields.cuid()
id!: string;
@Fields.string()
name!: string;
@Fields.string()
systemMessage?: string;
@Fields.json()
enabledMCPs?: string[];
@Fields.string()
branchedFromId?: string | null;
@Fields.number()
branchedFromMessageIndex?: number | null;
}
export type ProjectEntityMembers = MembersOnly<ProjectEntity>;
const projectsRepo = repo(ProjectEntity, idb);
const LOCAL_STORAGE_KEY = "hf_inf_pg_active_pid";
export const DEFAULT_PROJECT_ID = "default";
const defaultProj = projectsRepo.create({ id: DEFAULT_PROJECT_ID, name: "Default" });
class Projects {
#projects: Record<ProjectEntity["id"], ProjectEntity> = $state({ default: defaultProj });
#activeId = new PersistedState(LOCAL_STORAGE_KEY, "default");
get activeId() {
return this.#activeId.current;
}
set activeId(id: string) {
this.#activeId.current = id;
}
constructor() {
projectsRepo.find().then(res => {
if (!res.some(p => p.id === this.activeId)) this.activeId === DEFAULT_PROJECT_ID;
res.forEach(p => {
if (dequal(this.#projects[p.id], p)) return;
this.#projects[p.id] = p;
});
});
}
async create(args: Omit<ProjectEntity, "id">): Promise<string> {
const p = await projectsRepo.save({ ...args });
this.#projects[p.id] = p;
return p.id;
}
saveProject = async (args: { name: string; moveCheckpoints?: boolean }) => {
const defaultProject = this.all.find(p => p.id === DEFAULT_PROJECT_ID);
if (!defaultProject) return;
const id = await this.create({ name: args.name, systemMessage: defaultProject.systemMessage });
if (args.moveCheckpoints) {
checkpoints.migrate(defaultProject.id, id);
}
// conversations.migrate(defaultProject.id, id).then(_ => (this.#activeId.current = id));
conversations.migrate(defaultProject.id, id).then(() => {
this.activeId = id;
});
return id;
};
get current() {
return this.#projects[this.activeId];
}
get all() {
return Object.values(this.#projects);
}
async update(data: ProjectEntity) {
if (!data.id) return;
await projectsRepo.upsert({ where: { id: data.id }, set: data });
this.#projects[data.id] = { ...data };
}
async delete(id: string) {
if (!id) return;
await projectsRepo.delete(id);
await conversations.deleteAllFrom(id);
delete this.#projects[id];
if (this.activeId === id) {
this.activeId = DEFAULT_PROJECT_ID;
}
}
branch = async (fromProjectId: string, messageIndex: number): Promise<string> => {
const fromProject = this.#projects[fromProjectId];
if (!fromProject) throw new Error("Source project not found");
// Create new project with branching info
const newProjectId = await this.create({
name: `${fromProject.name} (branch)`,
systemMessage: fromProject.systemMessage,
branchedFromId: fromProjectId,
branchedFromMessageIndex: messageIndex,
});
// Copy conversations up to the specified message index
await conversations.duplicateUpToMessage(fromProjectId, newProjectId, messageIndex);
// Switch to the new project
this.activeId = newProjectId;
return newProjectId;
};
getBranchedFromProject = (projectId: string) => {
const project = this.#projects[projectId];
if (!project?.branchedFromId) return null;
const originalProject = this.#projects[project.branchedFromId];
return originalProject;
};
clearBranchStatus = async (projectId: string) => {
const project = this.#projects[projectId];
if (!project?.branchedFromId) return;
await this.update({
...project,
branchedFromId: null,
branchedFromMessageIndex: null,
});
};
}
export const projects = new Projects();
|