Skip to content
Snippets Groups Projects
llama-pack.ts 4.59 KiB
Newer Older
  • Learn to ignore specific revisions
  • import fs from "fs/promises";
    
    import path from "path";
    
    import { parse } from "smol-toml";
    import {
      LLAMA_PACK_FOLDER,
      LLAMA_PACK_FOLDER_PATH,
      LLAMA_PACK_OWNER,
      LLAMA_PACK_REPO,
    } from "./constant";
    
    import { copy } from "./copy";
    
    import { templatesDir } from "./dir";
    
    import { addDependencies, installPythonDependencies } from "./python";
    
    import { getRepoRawContent } from "./repo";
    import { InstallTemplateArgs } from "./types";
    
    
    const getLlamaPackFolderSHA = async () => {
      const url = `https://api.github.com/repos/${LLAMA_PACK_OWNER}/${LLAMA_PACK_REPO}/contents`;
      const response = await got(url, {
        responseType: "json",
      });
      const data = response.body as any[];
      const llamaPackFolder = data.find((item) => item.name === LLAMA_PACK_FOLDER);
      return llamaPackFolder.sha;
    };
    
    const getLLamaPackFolderTree = async (
      sha: string,
    ): Promise<
      Array<{
        path: string;
      }>
    > => {
      const url = `https://api.github.com/repos/${LLAMA_PACK_OWNER}/${LLAMA_PACK_REPO}/git/trees/${sha}?recursive=1`;
      const response = await got(url, {
        responseType: "json",
      });
      return (response.body as any).tree;
    };
    
    
    export async function getAvailableLlamapackOptions(): Promise<
      {
        name: string;
        folderPath: string;
      }[]
    > {
    
      const EXAMPLE_RELATIVE_PATH = "/examples/example.py";
      const PACK_FOLDER_SUBFIX = "llama-index-packs";
    
      const llamaPackFolderSHA = await getLlamaPackFolderSHA();
      const llamaPackTree = await getLLamaPackFolderTree(llamaPackFolderSHA);
    
      // Return options that have example files
      const exampleFiles = llamaPackTree.filter((item) =>
        item.path.endsWith(EXAMPLE_RELATIVE_PATH),
      );
      const options = exampleFiles.map((file) => {
        const packFolder = file.path.substring(
          0,
          file.path.indexOf(EXAMPLE_RELATIVE_PATH),
        );
        const packName = packFolder.substring(PACK_FOLDER_SUBFIX.length + 1);
        return {
          name: packName,
          folderPath: packFolder,
        };
      });
      return options;
    
    }
    
    const copyLlamapackEmptyProject = async ({
      root,
    }: Pick<InstallTemplateArgs, "root">) => {
      const templatePath = path.join(
    
        templatesDir,
        "components/sample-projects/llamapack",
    
      );
      await copy("**", root, {
        parents: true,
        cwd: templatePath,
      });
    };
    
    const copyData = async ({
      root,
    }: Pick<InstallTemplateArgs, "root" | "llamapack">) => {
    
      const dataPath = path.join(templatesDir, "components/data");
    
      await copy("**", path.join(root, "data"), {
        parents: true,
        cwd: dataPath,
      });
    };
    
    const installLlamapackExample = async ({
      root,
      llamapack,
    }: Pick<InstallTemplateArgs, "root" | "llamapack">) => {
      const exampleFileName = "example.py";
      const readmeFileName = "README.md";
    
      const projectTomlFileName = "pyproject.toml";
      const exampleFilePath = `${LLAMA_PACK_FOLDER_PATH}/${llamapack}/examples/${exampleFileName}`;
      const readmeFilePath = `${LLAMA_PACK_FOLDER_PATH}/${llamapack}/${readmeFileName}`;
      const projectTomlFilePath = `${LLAMA_PACK_FOLDER_PATH}/${llamapack}/${projectTomlFileName}`;
    
    
      // Download example.py from llamapack and save to root
      const exampleContent = await getRepoRawContent(exampleFilePath);
      await fs.writeFile(path.join(root, exampleFileName), exampleContent);
    
      // Download README.md from llamapack and combine with README-template.md,
      // save to root and then delete template file
      const readmeContent = await getRepoRawContent(readmeFilePath);
      const readmeTemplateContent = await fs.readFile(
        path.join(root, "README-template.md"),
        "utf-8",
      );
      await fs.writeFile(
        path.join(root, readmeFileName),
        `${readmeContent}\n${readmeTemplateContent}`,
      );
      await fs.unlink(path.join(root, "README-template.md"));
    
    
      // Download pyproject.toml from llamapack, parse it to get package name and version,
      // then add it as a dependency to current toml file in the project
      const projectTomlContent = await getRepoRawContent(projectTomlFilePath);
      const fileParsed = parse(projectTomlContent) as any;
      const packageName = fileParsed.tool.poetry.name;
      const packageVersion = fileParsed.tool.poetry.version;
      await addDependencies(root, [
        {
          name: packageName,
          version: packageVersion,
        },
      ]);
    
    };
    
    export const installLlamapackProject = async ({
      root,
      llamapack,
      postInstallAction,
    }: Pick<InstallTemplateArgs, "root" | "llamapack" | "postInstallAction">) => {
      console.log("\nInstalling Llamapack project:", llamapack!);
      await copyLlamapackEmptyProject({ root });
      await copyData({ root });
      await installLlamapackExample({ root, llamapack });
    
      if (postInstallAction === "runApp" || postInstallAction === "dependencies") {
    
        installPythonDependencies({ noRoot: true });