mirror of
https://github.com/run-llama/create-llama.git
synced 2026-07-19 23:13:36 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 53e1cd56e7 | |||
| 0a2e12a2bb |
@@ -9,9 +9,6 @@ on:
|
||||
paths-ignore:
|
||||
- "llama-index-server/**"
|
||||
|
||||
env:
|
||||
POETRY_VERSION: "1.6.1"
|
||||
|
||||
jobs:
|
||||
e2e-python:
|
||||
name: python
|
||||
@@ -36,10 +33,10 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: ${{ env.POETRY_VERSION }}
|
||||
- name: Install uv
|
||||
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
- name: Add uv to PATH # Ensure uv is available in subsequent steps
|
||||
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||
|
||||
- uses: pnpm/action-setup@v3
|
||||
|
||||
@@ -106,10 +103,10 @@ jobs:
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: ${{ env.POETRY_VERSION }}
|
||||
- name: Install uv
|
||||
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
- name: Add uv to PATH # Ensure uv is available in subsequent steps
|
||||
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||
|
||||
- uses: pnpm/action-setup@v3
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# create-llama
|
||||
|
||||
## 0.5.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 0a2e12a: Use uv as the default package manager
|
||||
|
||||
## 0.5.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -55,7 +55,7 @@ Then re-start your app. Remember you'll need to re-run `generate` if you add new
|
||||
If you're using the Python backend, you can trigger indexing of your data by calling:
|
||||
|
||||
```bash
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
## Customizing the AI models
|
||||
|
||||
@@ -195,32 +195,47 @@ async function createAndCheckLlamaProject({
|
||||
const pyprojectPath = path.join(projectPath, "pyproject.toml");
|
||||
expect(fs.existsSync(pyprojectPath)).toBeTruthy();
|
||||
|
||||
const env = {
|
||||
// Modify environment for the command
|
||||
const commandEnv = {
|
||||
...process.env,
|
||||
POETRY_VIRTUALENVS_IN_PROJECT: "true",
|
||||
};
|
||||
|
||||
// Run poetry install
|
||||
console.log("Running uv venv...");
|
||||
try {
|
||||
const { stdout: installStdout, stderr: installStderr } = await execAsync(
|
||||
"poetry install",
|
||||
{ cwd: projectPath, env },
|
||||
const { stdout: venvStdout, stderr: venvStderr } = await execAsync(
|
||||
"uv venv",
|
||||
{ cwd: projectPath, env: commandEnv },
|
||||
);
|
||||
console.log("poetry install stdout:", installStdout);
|
||||
console.error("poetry install stderr:", installStderr);
|
||||
console.log("uv venv stdout:", venvStdout);
|
||||
console.error("uv venv stderr:", venvStderr);
|
||||
} catch (error) {
|
||||
console.error("Error running poetry install:", error);
|
||||
throw error;
|
||||
console.error("Error running uv venv:", error);
|
||||
throw error; // Re-throw error to fail the test
|
||||
}
|
||||
|
||||
// Run poetry run mypy
|
||||
console.log("Running uv sync...");
|
||||
try {
|
||||
const { stdout: syncStdout, stderr: syncStderr } = await execAsync(
|
||||
"uv sync --all-extras",
|
||||
{ cwd: projectPath, env: commandEnv },
|
||||
);
|
||||
console.log("uv sync stdout:", syncStdout);
|
||||
console.error("uv sync stderr:", syncStderr);
|
||||
} catch (error) {
|
||||
console.error("Error running uv sync:", error);
|
||||
throw error; // Re-throw error to fail the test
|
||||
}
|
||||
|
||||
console.log("Running uv run mypy ....");
|
||||
try {
|
||||
const { stdout: mypyStdout, stderr: mypyStderr } = await execAsync(
|
||||
"poetry run mypy .",
|
||||
{ cwd: projectPath, env },
|
||||
"uv run mypy .",
|
||||
{ cwd: projectPath, env: commandEnv },
|
||||
);
|
||||
console.log("poetry run mypy stdout:", mypyStdout);
|
||||
console.error("poetry run mypy stderr:", mypyStderr);
|
||||
console.log("uv run mypy stdout:", mypyStdout);
|
||||
console.error("uv run mypy stderr:", mypyStderr);
|
||||
// Assuming mypy success means no output or specific success message
|
||||
// Adjust checks based on actual expected mypy output
|
||||
} catch (error) {
|
||||
console.error("Error running mypy:", error);
|
||||
throw error;
|
||||
|
||||
+11
-5
@@ -9,7 +9,6 @@ import { createBackendEnvFile, createFrontendEnvFile } from "./env-variables";
|
||||
import { PackageManager } from "./get-pkg-manager";
|
||||
import { installLlamapackProject } from "./llama-pack";
|
||||
import { makeDir } from "./make-dir";
|
||||
import { isHavingPoetryLockFile, tryPoetryRun } from "./poetry";
|
||||
import { installPythonTemplate } from "./python";
|
||||
import { downloadAndExtractRepo } from "./repo";
|
||||
import { ConfigFileType, writeToolsConfig } from "./tools";
|
||||
@@ -22,6 +21,7 @@ import {
|
||||
TemplateVectorDB,
|
||||
} from "./types";
|
||||
import { installTSTemplate } from "./typescript";
|
||||
import { isHavingUvLockFile, tryUvRun } from "./uv";
|
||||
|
||||
const checkForGenerateScript = (
|
||||
modelConfig: ModelConfig,
|
||||
@@ -64,7 +64,7 @@ async function generateContextData(
|
||||
if (packageManager) {
|
||||
const runGenerate = `${cyan(
|
||||
framework === "fastapi"
|
||||
? "poetry run generate"
|
||||
? "uv run generate"
|
||||
: `${packageManager} run generate`,
|
||||
)}`;
|
||||
|
||||
@@ -78,15 +78,21 @@ async function generateContextData(
|
||||
if (!missingSettings.length) {
|
||||
// If all the required environment variables are set, run the generate script
|
||||
if (framework === "fastapi") {
|
||||
if (isHavingPoetryLockFile()) {
|
||||
if (isHavingUvLockFile()) {
|
||||
console.log(`Running ${runGenerate} to generate the context data.`);
|
||||
const result = tryPoetryRun("poetry run generate");
|
||||
const result = tryUvRun("generate");
|
||||
if (!result) {
|
||||
console.log(`Failed to run ${runGenerate}.`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`Generated context data`);
|
||||
return;
|
||||
} else {
|
||||
console.log(
|
||||
picocolors.yellow(
|
||||
`\nWarning: uv.lock not found. Dependency installation might be incomplete. Skipping context generation.\nIf dependencies were installed, try running '${runGenerate}' manually.\n`,
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.log(`Running ${runGenerate} to generate the context data.`);
|
||||
@@ -103,7 +109,7 @@ async function generateContextData(
|
||||
const downloadFile = async (url: string, destPath: string) => {
|
||||
const response = await fetch(url);
|
||||
const fileBuffer = await response.arrayBuffer();
|
||||
await fsExtra.writeFile(destPath, Buffer.from(fileBuffer));
|
||||
await fsExtra.writeFile(destPath, new Uint8Array(fileBuffer));
|
||||
};
|
||||
|
||||
const prepareContextData = async (
|
||||
|
||||
@@ -143,6 +143,6 @@ export const installLlamapackProject = async ({
|
||||
await copyData({ root });
|
||||
await installLlamapackExample({ root, llamapack });
|
||||
if (postInstallAction === "runApp" || postInstallAction === "dependencies") {
|
||||
installPythonDependencies({ noRoot: true });
|
||||
installPythonDependencies();
|
||||
}
|
||||
};
|
||||
|
||||
+135
-104
@@ -3,10 +3,10 @@ import path from "path";
|
||||
import { cyan, red } from "picocolors";
|
||||
import { parse, stringify } from "smol-toml";
|
||||
import terminalLink from "terminal-link";
|
||||
import { isUvAvailable, tryUvSync } from "./uv";
|
||||
|
||||
import { assetRelocator, copy } from "./copy";
|
||||
import { templatesDir } from "./dir";
|
||||
import { isPoetryAvailable, tryPoetryInstall } from "./poetry";
|
||||
import { Tool } from "./tools";
|
||||
import {
|
||||
InstallTemplateArgs,
|
||||
@@ -39,21 +39,21 @@ const getAdditionalDependencies = (
|
||||
case "mongo": {
|
||||
dependencies.push({
|
||||
name: "llama-index-vector-stores-mongodb",
|
||||
version: "^0.6.0",
|
||||
version: ">=0.3.2,<0.4.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "pg": {
|
||||
dependencies.push({
|
||||
name: "llama-index-vector-stores-postgres",
|
||||
version: "^0.3.2",
|
||||
version: ">=0.3.2,<0.4.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "pinecone": {
|
||||
dependencies.push({
|
||||
name: "llama-index-vector-stores-pinecone",
|
||||
version: "^0.4.1",
|
||||
version: ">=0.4.1,<0.5.0",
|
||||
constraints: {
|
||||
python: ">=3.11,<3.13",
|
||||
},
|
||||
@@ -63,25 +63,25 @@ const getAdditionalDependencies = (
|
||||
case "milvus": {
|
||||
dependencies.push({
|
||||
name: "llama-index-vector-stores-milvus",
|
||||
version: "^0.3.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "pymilvus",
|
||||
version: "2.4.4",
|
||||
version: ">=2.4.4,<3.0.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "astra": {
|
||||
dependencies.push({
|
||||
name: "llama-index-vector-stores-astra-db",
|
||||
version: "^0.4.0",
|
||||
version: ">=0.4.0,<0.5.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "qdrant": {
|
||||
dependencies.push({
|
||||
name: "llama-index-vector-stores-qdrant",
|
||||
version: "^0.4.0",
|
||||
version: ">=0.4.0,<0.5.0",
|
||||
constraints: {
|
||||
python: ">=3.11,<3.13",
|
||||
},
|
||||
@@ -91,21 +91,21 @@ const getAdditionalDependencies = (
|
||||
case "chroma": {
|
||||
dependencies.push({
|
||||
name: "llama-index-vector-stores-chroma",
|
||||
version: "^0.4.0",
|
||||
version: ">=0.4.0,<0.5.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "weaviate": {
|
||||
dependencies.push({
|
||||
name: "llama-index-vector-stores-weaviate",
|
||||
version: "^1.2.3",
|
||||
version: ">=1.2.3,<2.0.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "llamacloud":
|
||||
dependencies.push({
|
||||
name: "llama-index-indices-managed-llama-cloud",
|
||||
version: "0.6.3",
|
||||
version: ">=0.6.3,<0.7.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -118,28 +118,28 @@ const getAdditionalDependencies = (
|
||||
case "file":
|
||||
dependencies.push({
|
||||
name: "docx2txt",
|
||||
version: "^0.8",
|
||||
version: ">=0.8,<0.9",
|
||||
});
|
||||
break;
|
||||
case "web":
|
||||
dependencies.push({
|
||||
name: "llama-index-readers-web",
|
||||
version: "^0.3.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
break;
|
||||
case "db":
|
||||
dependencies.push({
|
||||
name: "llama-index-readers-database",
|
||||
version: "^0.3.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "pymysql",
|
||||
version: "^1.1.0",
|
||||
version: ">=1.1.0,<2.0.0",
|
||||
extras: ["rsa"],
|
||||
});
|
||||
dependencies.push({
|
||||
name: "psycopg2-binary",
|
||||
version: "^2.9.9",
|
||||
version: ">=2.9.9,<3.0.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -158,114 +158,102 @@ const getAdditionalDependencies = (
|
||||
case "ollama":
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-ollama",
|
||||
version: "0.3.0",
|
||||
version: ">=0.5.0,<0.6.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-embeddings-ollama",
|
||||
version: "0.3.0",
|
||||
version: ">=0.6.0,<0.7.0",
|
||||
});
|
||||
break;
|
||||
case "openai":
|
||||
if (templateType !== "multiagent") {
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-openai",
|
||||
version: "^0.3.2",
|
||||
version: ">=0.3.2,<0.4.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-embeddings-openai",
|
||||
version: "^0.3.1",
|
||||
version: ">=0.3.1,<0.4.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-agent-openai",
|
||||
version: "^0.4.0",
|
||||
version: ">=0.4.0,<0.5.0",
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "groq":
|
||||
// Fastembed==0.2.0 does not support python3.13 at the moment
|
||||
// Fixed the python version less than 3.13
|
||||
dependencies.push({
|
||||
name: "python",
|
||||
version: "^3.11,<3.13",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-groq",
|
||||
version: "0.2.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-embeddings-fastembed",
|
||||
version: "^0.2.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
break;
|
||||
case "anthropic":
|
||||
// Fastembed==0.2.0 does not support python3.13 at the moment
|
||||
// Fixed the python version less than 3.13
|
||||
dependencies.push({
|
||||
name: "python",
|
||||
version: "^3.11,<3.13",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-anthropic",
|
||||
version: "0.3.0",
|
||||
version: ">=0.6.0,<0.7.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-embeddings-fastembed",
|
||||
version: "^0.2.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
break;
|
||||
case "gemini":
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-gemini",
|
||||
version: "0.3.4",
|
||||
version: ">=0.4.0,<0.5.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-embeddings-gemini",
|
||||
version: "^0.2.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
break;
|
||||
case "mistral":
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-mistralai",
|
||||
version: "0.2.1",
|
||||
version: ">=0.4.0,<0.5.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-embeddings-mistralai",
|
||||
version: "0.2.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
break;
|
||||
case "azure-openai":
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-azure-openai",
|
||||
version: "0.2.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-embeddings-azure-openai",
|
||||
version: "0.2.4",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
break;
|
||||
case "huggingface":
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-huggingface",
|
||||
version: "^0.3.5",
|
||||
version: ">=0.5.0,<0.6.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-embeddings-huggingface",
|
||||
version: "^0.3.1",
|
||||
version: ">=0.5.0,<0.6.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "optimum",
|
||||
version: "^1.23.3",
|
||||
version: ">=1.23.3,<2.0.0",
|
||||
extras: ["onnxruntime"],
|
||||
});
|
||||
break;
|
||||
case "t-systems":
|
||||
dependencies.push({
|
||||
name: "llama-index-agent-openai",
|
||||
version: "0.3.0",
|
||||
version: ">=0.4.0,<0.5.0",
|
||||
});
|
||||
dependencies.push({
|
||||
name: "llama-index-llms-openai-like",
|
||||
version: "0.2.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -274,13 +262,13 @@ const getAdditionalDependencies = (
|
||||
if (observability === "traceloop") {
|
||||
dependencies.push({
|
||||
name: "traceloop-sdk",
|
||||
version: "^0.15.11",
|
||||
version: ">=0.15.11,<0.16.0",
|
||||
});
|
||||
}
|
||||
if (observability === "llamatrace") {
|
||||
dependencies.push({
|
||||
name: "llama-index-callbacks-arize-phoenix",
|
||||
version: "^0.3.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -288,42 +276,6 @@ const getAdditionalDependencies = (
|
||||
return dependencies;
|
||||
};
|
||||
|
||||
const mergePoetryDependencies = (
|
||||
dependencies: Dependency[],
|
||||
existingDependencies: Record<string, Omit<Dependency, "name"> | string>,
|
||||
) => {
|
||||
for (const dependency of dependencies) {
|
||||
let value = existingDependencies[dependency.name] ?? {};
|
||||
|
||||
// default string value is equal to attribute "version"
|
||||
if (typeof value === "string") {
|
||||
value = { version: value };
|
||||
}
|
||||
|
||||
value.version = dependency.version ?? value.version;
|
||||
value.extras = dependency.extras ?? value.extras;
|
||||
|
||||
// Merge constraints if they exist
|
||||
if (dependency.constraints) {
|
||||
value = { ...value, ...dependency.constraints };
|
||||
}
|
||||
|
||||
if (value.version === undefined) {
|
||||
throw new Error(
|
||||
`Dependency "${dependency.name}" is missing attribute "version"!`,
|
||||
);
|
||||
}
|
||||
|
||||
// Serialize as object if there are any additional properties
|
||||
if (Object.keys(value).length > 1) {
|
||||
existingDependencies[dependency.name] = value;
|
||||
} else {
|
||||
// Otherwise, serialize just the version string
|
||||
existingDependencies[dependency.name] = value.version;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const copyRouterCode = async (root: string, tools: Tool[]) => {
|
||||
// Copy sandbox router if the artifact tool is selected
|
||||
if (tools?.some((t) => t.name === "artifact")) {
|
||||
@@ -346,19 +298,100 @@ export const addDependencies = async (
|
||||
// Parse toml file
|
||||
const file = path.join(projectDir, FILENAME);
|
||||
const fileContent = await fs.readFile(file, "utf8");
|
||||
const fileParsed = parse(fileContent);
|
||||
let fileParsed: any;
|
||||
try {
|
||||
fileParsed = parse(fileContent);
|
||||
} catch (parseError) {
|
||||
console.error(`Error parsing ${FILENAME}:`, parseError);
|
||||
throw new Error(
|
||||
`Failed to parse ${FILENAME}. Please ensure it's valid TOML.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Modify toml dependencies
|
||||
const tool = fileParsed.tool as any;
|
||||
const existingDependencies = tool.poetry.dependencies;
|
||||
mergePoetryDependencies(dependencies, existingDependencies);
|
||||
// Ensure [project] and [project.dependencies] exist
|
||||
if (!fileParsed.project) {
|
||||
fileParsed.project = {};
|
||||
}
|
||||
if (
|
||||
!fileParsed.project.dependencies ||
|
||||
!Array.isArray(fileParsed.project.dependencies)
|
||||
) {
|
||||
// If dependencies exist but aren't an array, log a warning or error.
|
||||
// For now, we'll overwrite it, assuming the intent is to use the standard array format.
|
||||
console.warn(
|
||||
`[project.dependencies] in ${FILENAME} is not an array. It will be overwritten.`,
|
||||
);
|
||||
fileParsed.project.dependencies = [];
|
||||
}
|
||||
|
||||
const existingDependencies: string[] = fileParsed.project.dependencies;
|
||||
const addedDeps: string[] = [];
|
||||
const updatedDeps: string[] = [];
|
||||
|
||||
// Add or update dependencies
|
||||
for (const newDep of dependencies) {
|
||||
let depString = newDep.name;
|
||||
if (newDep.extras && newDep.extras.length > 0) {
|
||||
depString += `[${newDep.extras.join(",")}]`;
|
||||
}
|
||||
if (newDep.version) {
|
||||
depString += newDep.version;
|
||||
}
|
||||
|
||||
let found = false;
|
||||
for (let i = 0; i < existingDependencies.length; i++) {
|
||||
const existingDepNameMatch =
|
||||
existingDependencies[i].match(/^([a-zA-Z0-9._-]+)/);
|
||||
if (
|
||||
existingDepNameMatch &&
|
||||
existingDepNameMatch[1].toLowerCase() === depString.toLowerCase()
|
||||
) {
|
||||
// Found existing dependency, update it
|
||||
if (existingDependencies[i] !== depString) {
|
||||
updatedDeps.push(`${existingDependencies[i]} -> ${depString}`);
|
||||
existingDependencies[i] = depString;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// Add new dependency
|
||||
existingDependencies.push(depString);
|
||||
addedDeps.push(depString);
|
||||
}
|
||||
// Handle python version constraints separately (if any)
|
||||
if (newDep.constraints?.python) {
|
||||
if (
|
||||
!fileParsed.project["requires-python"] ||
|
||||
fileParsed.project["requires-python"] !== newDep.constraints.python
|
||||
) {
|
||||
// This simple overwrite might not be ideal; merging constraints is complex.
|
||||
// For now, let's just set it if the new dependency has one.
|
||||
console.log(
|
||||
`Setting requires-python = "${newDep.constraints.python}" from dependency ${newDep.name}`,
|
||||
);
|
||||
fileParsed.project["requires-python"] = newDep.constraints.python;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write toml file
|
||||
const newFileContent = stringify(fileParsed);
|
||||
await fs.writeFile(file, newFileContent);
|
||||
|
||||
const dependenciesString = dependencies.map((d) => d.name).join(", ");
|
||||
console.log(`\nAdded ${dependenciesString} to ${cyan(FILENAME)}\n`);
|
||||
if (addedDeps.length > 0) {
|
||||
console.log(`\nAdded dependencies to ${cyan(FILENAME)}:`);
|
||||
addedDeps.forEach((dep) => console.log(` ${dep}`));
|
||||
}
|
||||
if (updatedDeps.length > 0) {
|
||||
console.log(`\nUpdated dependencies in ${cyan(FILENAME)}:`);
|
||||
updatedDeps.forEach((dep) => console.log(` ${dep}`));
|
||||
}
|
||||
if (addedDeps.length > 0 || updatedDeps.length > 0) {
|
||||
console.log(""); // Newline for spacing
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(
|
||||
`Error while updating dependencies for Poetry project file ${FILENAME}\n`,
|
||||
@@ -367,18 +400,16 @@ export const addDependencies = async (
|
||||
}
|
||||
};
|
||||
|
||||
export const installPythonDependencies = (
|
||||
{ noRoot }: { noRoot: boolean } = { noRoot: false },
|
||||
) => {
|
||||
if (isPoetryAvailable()) {
|
||||
export const installPythonDependencies = () => {
|
||||
if (isUvAvailable()) {
|
||||
console.log(
|
||||
`Installing python dependencies using poetry. This may take a while...`,
|
||||
`Installing Python dependencies using uv. This may take a while...`,
|
||||
);
|
||||
const installSuccessful = tryPoetryInstall(noRoot);
|
||||
const installSuccessful = tryUvSync();
|
||||
if (!installSuccessful) {
|
||||
console.error(
|
||||
red(
|
||||
"Installing dependencies using poetry failed. Please check error log above and try running create-llama again.",
|
||||
"Installing dependencies using uv failed. Please check the error log above and ensure uv is installed correctly.",
|
||||
),
|
||||
);
|
||||
process.exit(1);
|
||||
@@ -386,10 +417,10 @@ export const installPythonDependencies = (
|
||||
} else {
|
||||
console.error(
|
||||
red(
|
||||
`Poetry is not available in the current environment. Please check ${terminalLink(
|
||||
"Poetry Installation",
|
||||
`https://python-poetry.org/docs/#installation`,
|
||||
)} to install poetry first, then run create-llama again.`,
|
||||
`uv is not available in the current environment. Please check ${terminalLink(
|
||||
"uv Installation",
|
||||
`https://github.com/astral-sh/uv#installation`,
|
||||
)} to install uv first, then run create-llama again.`,
|
||||
),
|
||||
);
|
||||
process.exit(1);
|
||||
|
||||
+14
-4
@@ -34,14 +34,24 @@ export function runReflexApp(appPath: string, port: number) {
|
||||
"--frontend-port",
|
||||
port.toString(),
|
||||
];
|
||||
return createProcess("poetry", commandArgs, {
|
||||
return createProcess("uv", commandArgs, {
|
||||
stdio: "inherit",
|
||||
cwd: appPath,
|
||||
});
|
||||
}
|
||||
|
||||
export function runFastAPIApp(appPath: string, port: number) {
|
||||
return createProcess("poetry", ["run", "dev"], {
|
||||
export function runFastAPIApp(
|
||||
appPath: string,
|
||||
port: number,
|
||||
template: TemplateType,
|
||||
) {
|
||||
let commandArgs: string[];
|
||||
if (template === "streaming") {
|
||||
commandArgs = ["run", "dev"];
|
||||
} else {
|
||||
commandArgs = ["run", "fastapi", "dev", "--port", `${port}`];
|
||||
}
|
||||
return createProcess("uv", commandArgs, {
|
||||
stdio: "inherit",
|
||||
cwd: appPath,
|
||||
env: { ...process.env, APP_PORT: `${port}` },
|
||||
@@ -73,7 +83,7 @@ export async function runApp(
|
||||
: framework === "fastapi"
|
||||
? runFastAPIApp
|
||||
: runTSApp;
|
||||
await appRunner(appPath, port || defaultPort);
|
||||
await appRunner(appPath, port || defaultPort, template);
|
||||
} catch (error) {
|
||||
console.error("Failed to run app:", error);
|
||||
throw error;
|
||||
|
||||
+10
-10
@@ -41,7 +41,7 @@ export const supportedTools: Tool[] = [
|
||||
dependencies: [
|
||||
{
|
||||
name: "llama-index-tools-google",
|
||||
version: "^0.3.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
},
|
||||
],
|
||||
supportedFrameworks: ["fastapi"],
|
||||
@@ -62,7 +62,7 @@ export const supportedTools: Tool[] = [
|
||||
dependencies: [
|
||||
{
|
||||
name: "duckduckgo-search",
|
||||
version: "^6.3.5",
|
||||
version: ">=6.3.5,<7.0.0",
|
||||
},
|
||||
],
|
||||
supportedFrameworks: ["fastapi"], // TODO: Re-enable this tool once the duck-duck-scrape TypeScript library works again
|
||||
@@ -82,7 +82,7 @@ For better results, you can specify the region parameter to get results from a s
|
||||
dependencies: [
|
||||
{
|
||||
name: "llama-index-tools-wikipedia",
|
||||
version: "^0.3.0",
|
||||
version: ">=0.3.0,<0.4.0",
|
||||
},
|
||||
],
|
||||
supportedFrameworks: ["fastapi", "express", "nextjs"],
|
||||
@@ -102,11 +102,11 @@ For better results, you can specify the region parameter to get results from a s
|
||||
dependencies: [
|
||||
{
|
||||
name: "xhtml2pdf",
|
||||
version: "^0.2.14",
|
||||
version: ">=0.2.14,<0.3.0",
|
||||
},
|
||||
{
|
||||
name: "markdown",
|
||||
version: "^3.7",
|
||||
version: ">=3.7.0,<4.0.0",
|
||||
},
|
||||
],
|
||||
type: ToolType.LOCAL,
|
||||
@@ -124,7 +124,7 @@ For better results, you can specify the region parameter to get results from a s
|
||||
dependencies: [
|
||||
{
|
||||
name: "e2b_code_interpreter",
|
||||
version: "1.1.1",
|
||||
version: ">=1.1.1,<1.2.0",
|
||||
},
|
||||
],
|
||||
supportedFrameworks: ["fastapi", "express", "nextjs"],
|
||||
@@ -155,7 +155,7 @@ For better results, you can specify the region parameter to get results from a s
|
||||
dependencies: [
|
||||
{
|
||||
name: "e2b_code_interpreter",
|
||||
version: "1.1.1",
|
||||
version: ">=1.1.1,<1.2.0",
|
||||
},
|
||||
],
|
||||
supportedFrameworks: ["fastapi", "express", "nextjs"],
|
||||
@@ -184,7 +184,7 @@ For better results, you can specify the region parameter to get results from a s
|
||||
},
|
||||
{
|
||||
name: "jsonschema",
|
||||
version: "^4.22.0",
|
||||
version: ">=4.22.0,<5.0.0",
|
||||
},
|
||||
{
|
||||
name: "llama-index-tools-requests",
|
||||
@@ -247,11 +247,11 @@ For better results, you can specify the region parameter to get results from a s
|
||||
dependencies: [
|
||||
{
|
||||
name: "pandas",
|
||||
version: "^2.2.3",
|
||||
version: ">=2.2.3,<3.0.0",
|
||||
},
|
||||
{
|
||||
name: "tabulate",
|
||||
version: "^0.9.0",
|
||||
version: ">=0.9.0,<1.0.0",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Migrate poetry to uv
|
||||
import { execSync } from "child_process";
|
||||
import fs from "fs";
|
||||
import { red } from "picocolors";
|
||||
|
||||
export function isUvAvailable(): boolean {
|
||||
try {
|
||||
execSync("uv --version", { stdio: "ignore" });
|
||||
return true;
|
||||
} catch (_) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function tryUvSync(): boolean {
|
||||
try {
|
||||
console.log("Syncing environment with pyproject.toml...");
|
||||
execSync(`uv sync`, {
|
||||
stdio: "inherit",
|
||||
});
|
||||
return true;
|
||||
} catch (_) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function tryUvRun(command: string): boolean {
|
||||
try {
|
||||
// Use uv run <command>
|
||||
execSync(`uv run ${command}`, { stdio: "inherit" });
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(red(`Failed to run ${command}. Error: ${error}`));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isHavingUvLockFile(): boolean {
|
||||
try {
|
||||
// Check if uv.lock exists in the current directory
|
||||
return fs.existsSync("uv.lock");
|
||||
} catch (_) {}
|
||||
return false;
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-llama",
|
||||
"version": "0.5.9",
|
||||
"version": "0.5.10",
|
||||
"description": "Create LlamaIndex-powered apps with one command",
|
||||
"keywords": [
|
||||
"rag",
|
||||
|
||||
@@ -19,20 +19,20 @@ First, setup the environment with poetry:
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory. (E.g. you might need to configure an `OPENAI_API_KEY` if you're using OpenAI as model provider).
|
||||
Second, generate the embeddings of the documents in the `./data` directory:
|
||||
|
||||
```shell
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, run the development server:
|
||||
|
||||
```shell
|
||||
poetry run dev
|
||||
uv run dev
|
||||
```
|
||||
|
||||
Per default, the example is using the explicit workflow. You can change the example by setting the `EXAMPLE_TYPE` environment variable to `choreography` or `orchestrator`.
|
||||
@@ -52,7 +52,7 @@ Open [http://localhost:8000](http://localhost:8000) with your browser to start t
|
||||
To start the app optimized for **production**, run:
|
||||
|
||||
```
|
||||
poetry run prod
|
||||
uv run prod
|
||||
```
|
||||
|
||||
## Deployments
|
||||
|
||||
@@ -7,20 +7,20 @@ First, setup the environment with poetry:
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory. (E.g. you might need to configure an `OPENAI_API_KEY` if you're using OpenAI as model provider).
|
||||
Second, generate the embeddings of the documents in the `./data` directory:
|
||||
|
||||
```shell
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, run the development server:
|
||||
|
||||
```shell
|
||||
poetry run dev
|
||||
uv run dev
|
||||
```
|
||||
|
||||
## Use Case: Deep Research over own documents
|
||||
|
||||
@@ -7,7 +7,7 @@ First, setup the environment with poetry:
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory. (E.g. you might need to configure an `OPENAI_API_KEY` if you're using OpenAI as model provider and `E2B_API_KEY` for the [E2B's code interpreter tool](https://e2b.dev/docs)).
|
||||
@@ -15,13 +15,13 @@ Then check the parameters that have been pre-configured in the `.env` file in th
|
||||
Second, generate the embeddings of the documents in the `./data` directory:
|
||||
|
||||
```shell
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, run the development server:
|
||||
|
||||
```shell
|
||||
poetry run dev
|
||||
uv run dev
|
||||
```
|
||||
|
||||
The example provides one streaming API endpoint `/api/chat`.
|
||||
@@ -40,7 +40,7 @@ Open [http://localhost:8000](http://localhost:8000) with your browser to start t
|
||||
To start the app optimized for **production**, run:
|
||||
|
||||
```
|
||||
poetry run prod
|
||||
uv run prod
|
||||
```
|
||||
|
||||
## Deployments
|
||||
|
||||
@@ -7,7 +7,7 @@ First, setup the environment with poetry:
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory.
|
||||
@@ -16,7 +16,7 @@ Make sure you have the `OPENAI_API_KEY` set.
|
||||
Second, run the development server:
|
||||
|
||||
```shell
|
||||
poetry run dev
|
||||
uv run dev
|
||||
```
|
||||
|
||||
## Use Case: Filling Financial CSV Template
|
||||
@@ -46,7 +46,7 @@ Open [http://localhost:8000](http://localhost:8000) with your browser to start t
|
||||
To start the app optimized for **production**, run:
|
||||
|
||||
```
|
||||
poetry run prod
|
||||
uv run prod
|
||||
```
|
||||
|
||||
## Deployments
|
||||
|
||||
@@ -30,7 +30,7 @@ def get_chat_engine(params=None, event_handlers=None, **kwargs):
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=str(
|
||||
"StorageContext is empty - call 'poetry run generate' to generate the storage first"
|
||||
"StorageContext is empty - call 'uv run generate' to generate the storage first"
|
||||
),
|
||||
)
|
||||
if top_k != 0 and kwargs.get("similarity_top_k") is None:
|
||||
|
||||
@@ -10,7 +10,7 @@ class CrawlUrl(BaseModel):
|
||||
|
||||
|
||||
class WebLoaderConfig(BaseModel):
|
||||
driver_arguments: Optional[List[str]] = Field(default_factory=list)
|
||||
driver_arguments: Optional[List[str]] = Field(default=None)
|
||||
urls: List[CrawlUrl]
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ First, setup the environment with poetry:
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory. (E.g. you might need to configure an `OPENAI_API_KEY` if you're using OpenAI as model provider).
|
||||
@@ -15,13 +15,13 @@ Then check the parameters that have been pre-configured in the `.env` file in th
|
||||
Second, generate the embeddings of the example document in the `./data` directory:
|
||||
|
||||
```shell
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, start app with `reflex` command:
|
||||
|
||||
```shell
|
||||
poetry run reflex run
|
||||
uv run reflex run
|
||||
```
|
||||
|
||||
To deploy the application, refer to the Reflex deployment guide: https://reflex.dev/docs/hosting/deploy-quick-start/
|
||||
@@ -40,7 +40,7 @@ To get started:
|
||||
2. Review Process:
|
||||
- The system will automatically analyze your document against compliance guidelines
|
||||
- By default, it uses [GDPR](./data/gdpr.pdf) as the compliance benchmark
|
||||
- Custom guidelines can be used by adding your policy documents to the `./data` directory and running `poetry run generate` to update the embeddings
|
||||
- Custom guidelines can be used by adding your policy documents to the `./data` directory and running `uv run generate` to update the embeddings
|
||||
|
||||
The interface will display the analysis results for the compliance of the contract document.
|
||||
|
||||
|
||||
@@ -5,20 +5,6 @@ from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from llama_index.core import SimpleDirectoryReader
|
||||
from llama_index.core.llms import LLM
|
||||
from llama_index.core.prompts import ChatPromptTemplate
|
||||
from llama_index.core.retrievers import BaseRetriever
|
||||
from llama_index.core.settings import Settings
|
||||
from llama_index.core.workflow import (
|
||||
Context,
|
||||
Event,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
step,
|
||||
)
|
||||
|
||||
from app.config import (
|
||||
COMPLIANCE_REPORT_SYSTEM_PROMPT,
|
||||
COMPLIANCE_REPORT_USER_PROMPT,
|
||||
@@ -32,6 +18,19 @@ from app.models import (
|
||||
ContractClause,
|
||||
ContractExtraction,
|
||||
)
|
||||
from llama_index.core import SimpleDirectoryReader
|
||||
from llama_index.core.llms import LLM
|
||||
from llama_index.core.prompts import ChatPromptTemplate
|
||||
from llama_index.core.retrievers import BaseRetriever
|
||||
from llama_index.core.settings import Settings
|
||||
from llama_index.core.workflow import (
|
||||
Context,
|
||||
Event,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
Workflow,
|
||||
step,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -40,7 +39,7 @@ def get_workflow():
|
||||
index = get_index()
|
||||
if index is None:
|
||||
raise RuntimeError(
|
||||
"Index not found! Please run `poetry run generate` to populate an index first."
|
||||
"Index not found! Please run `uv run generate` to populate an index first."
|
||||
)
|
||||
return ContractReviewWorkflow(
|
||||
guideline_retriever=index.as_retriever(),
|
||||
|
||||
@@ -1,44 +1,33 @@
|
||||
[tool]
|
||||
[tool.poetry]
|
||||
[project]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = [ "Marcus Schiesser <mail@marcusschiesser.de>" ]
|
||||
authors = [ { name = "Marcus Schiesser", email = "mail@marcusschiesser.de" } ]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11,<4.0"
|
||||
dependencies = [
|
||||
"fastapi>=0.109.1",
|
||||
"python-dotenv>=1.0.0",
|
||||
"pydantic<2.10",
|
||||
"llama-index>=0.12.1",
|
||||
"cachetools>=5.3.3",
|
||||
"reflex>=0.6.2.post1",
|
||||
]
|
||||
|
||||
[tool.poetry.scripts]
|
||||
[project.scripts]
|
||||
generate = "app.engine.generate:generate_datasource"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11,<4.0"
|
||||
fastapi = "^0.109.1"
|
||||
python-dotenv = "^1.0.0"
|
||||
pydantic = "<2.10"
|
||||
llama-index = "^0.12.1"
|
||||
cachetools = "^5.3.3"
|
||||
reflex = "^0.6.2.post1"
|
||||
|
||||
[tool.poetry.dependencies.uvicorn]
|
||||
extras = [ "standard" ]
|
||||
version = "^0.23.2"
|
||||
|
||||
[tool.poetry.dependencies.docx2txt]
|
||||
version = "^0.8"
|
||||
|
||||
[tool.poetry.dependencies.llama-index-llms-openai]
|
||||
version = "^0.3.2"
|
||||
|
||||
[tool.poetry.dependencies.llama-index-embeddings-openai]
|
||||
version = "^0.3.1"
|
||||
|
||||
[tool.poetry.dependencies.llama-index-agent-openai]
|
||||
version = "^0.4.0"
|
||||
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest-asyncio = "^0.25.0"
|
||||
pytest = "^8.3.4"
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"mypy>=1.8.0",
|
||||
"pytest>=8.3.5",
|
||||
"pytest-asyncio>=0.25.3",
|
||||
"docx2txt>=0.8",
|
||||
"llama-index-llms-openai>=0.3.2",
|
||||
"llama-index-embeddings-openai>=0.3.1",
|
||||
"llama-index-agent-openai>=0.4.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = [ "poetry-core" ]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
requires = [ "hatchling>=1.24" ]
|
||||
build-backend = "hatchling.build"
|
||||
@@ -7,7 +7,7 @@ First, setup the environment with poetry:
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory. (E.g. you might need to configure an `OPENAI_API_KEY` if you're using OpenAI as model provider).
|
||||
@@ -15,13 +15,13 @@ Then check the parameters that have been pre-configured in the `.env` file in th
|
||||
Second, generate the embeddings of the example document in the `./data` directory:
|
||||
|
||||
```shell
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, start app with `reflex` command:
|
||||
|
||||
```shell
|
||||
poetry run reflex run
|
||||
uv run reflex run
|
||||
```
|
||||
|
||||
To deploy the application, refer to the Reflex deployment guide: https://reflex.dev/docs/hosting/deploy-quick-start/
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import logging
|
||||
|
||||
import reflex as rx
|
||||
from app.services.model import DEFAULT_MODEL
|
||||
from app.services.extractor import ExtractorService, InvalidModelCode
|
||||
from app.services.model import DEFAULT_MODEL
|
||||
|
||||
logger = logging.getLogger("uvicorn")
|
||||
|
||||
@@ -13,7 +14,7 @@ class StructuredQuery(rx.State):
|
||||
code: str = DEFAULT_MODEL
|
||||
error: str = None
|
||||
|
||||
@rx.background
|
||||
@rx.event(background=True)
|
||||
async def handle_query(self):
|
||||
async with self:
|
||||
if not self.query:
|
||||
|
||||
@@ -18,7 +18,7 @@ class MonacoComponent(rx.Component):
|
||||
theme: rx.Var[str] = rx.color_mode_cond("light", "vs-dark") # type: ignore
|
||||
|
||||
# The width of the editor.
|
||||
line: rx.Var[int] = rx.Var.create_safe(1, _var_is_string=False)
|
||||
line: rx.Var[int] = rx.Var.create_safe(1)
|
||||
|
||||
# The height of the editor.
|
||||
width: rx.Var[str]
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
[tool.poetry]
|
||||
[project]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Marcus Schiesser <mail@marcusschiesser.de>"]
|
||||
authors = [ { name = "Marcus Schiesser", email = "mail@marcusschiesser.de" } ]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11,<4.0"
|
||||
dependencies = [
|
||||
"fastapi>=0.109.1",
|
||||
"uvicorn>=0.23.2",
|
||||
"python-dotenv>=1.0.0",
|
||||
"pydantic<2.10",
|
||||
"llama-index>=0.12.1",
|
||||
"cachetools>=5.3.3",
|
||||
"reflex>=0.6.2.post1",
|
||||
]
|
||||
|
||||
[tool.poetry.scripts]
|
||||
[project.scripts]
|
||||
generate = "app.engine.generate:generate_datasource"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11,<4.0"
|
||||
fastapi = "^0.109.1"
|
||||
uvicorn = { extras = ["standard"], version = "^0.23.2" }
|
||||
python-dotenv = "^1.0.0"
|
||||
pydantic = "<2.10"
|
||||
llama-index = "^0.12.1"
|
||||
cachetools = "^5.3.3"
|
||||
reflex = "^0.6.2.post1"
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"mypy>=1.8.0",
|
||||
"pytest>=8.3.5",
|
||||
"pytest-asyncio>=0.25.3",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
requires = [ "hatchling>=1.24" ]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
@@ -5,7 +5,7 @@ def generate_filters(doc_ids):
|
||||
"""
|
||||
Generate public/private document filters based on the doc_ids and the vector store.
|
||||
"""
|
||||
# public documents (ingested by "poetry run generate" or in the LlamaCloud UI) don't have the "private" field
|
||||
# public documents (ingested by "uv run generate" or in the LlamaCloud UI) don't have the "private" field
|
||||
public_doc_filter = MetadataFilter(
|
||||
key="private",
|
||||
value=None,
|
||||
|
||||
@@ -2,12 +2,12 @@ This is a [LlamaIndex](https://www.llamaindex.ai/) simple agentic RAG project us
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, setup the environment with poetry:
|
||||
First, setup the environment with uv:
|
||||
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory.
|
||||
@@ -16,13 +16,13 @@ Make sure you have set the `OPENAI_API_KEY` for the LLM.
|
||||
Second, generate the embeddings of the documents in the `./data` directory:
|
||||
|
||||
```shell
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, run the development server:
|
||||
|
||||
```shell
|
||||
poetry run dev
|
||||
uv run fastapi dev
|
||||
```
|
||||
|
||||
Then open [http://localhost:8000](http://localhost:8000) with your browser to start the chat UI.
|
||||
@@ -30,7 +30,7 @@ Then open [http://localhost:8000](http://localhost:8000) with your browser to st
|
||||
To start the app optimized for **production**, run:
|
||||
|
||||
```
|
||||
poetry run prod
|
||||
uv run fastapi run
|
||||
```
|
||||
|
||||
## Configure LLM and Embedding Model
|
||||
|
||||
@@ -12,7 +12,7 @@ def create_workflow(chat_request: Optional[ChatRequest] = None) -> AgentWorkflow
|
||||
index = get_index(chat_request=chat_request)
|
||||
if index is None:
|
||||
raise RuntimeError(
|
||||
"Index not found! Please run `poetry run generate` to index the data first."
|
||||
"Index not found! Please run `uv run generate` to index the data first."
|
||||
)
|
||||
query_tool = get_query_engine_tool(index=index)
|
||||
return AgentWorkflow.from_tools_or_functions(
|
||||
|
||||
@@ -2,12 +2,12 @@ This is a [LlamaIndex](https://www.llamaindex.ai/) multi-agents project using [W
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, setup the environment with poetry:
|
||||
First, setup the environment with uv:
|
||||
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory.
|
||||
@@ -16,13 +16,13 @@ Make sure you have set the `OPENAI_API_KEY` for the LLM.
|
||||
Second, generate the embeddings of the documents in the `./data` directory:
|
||||
|
||||
```shell
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, run the development server:
|
||||
|
||||
```shell
|
||||
poetry run dev
|
||||
uv run fastapi dev
|
||||
```
|
||||
|
||||
Then open [http://localhost:8000](http://localhost:8000) with your browser to start the chat UI.
|
||||
@@ -30,7 +30,7 @@ Then open [http://localhost:8000](http://localhost:8000) with your browser to st
|
||||
To start the app optimized for **production**, run:
|
||||
|
||||
```
|
||||
poetry run prod
|
||||
uv run fastapi run
|
||||
```
|
||||
|
||||
## Configure LLM and Embedding Model
|
||||
@@ -56,7 +56,7 @@ To customize the UI, you can start by modifying the [./components/ui_event.jsx](
|
||||
You can also generate a new code for the workflow using LLM by running the following command:
|
||||
|
||||
```
|
||||
poetry run generate:ui
|
||||
uv run generate_ui
|
||||
```
|
||||
|
||||
## Learn More
|
||||
|
||||
@@ -2,12 +2,12 @@ This is a [LlamaIndex](https://www.llamaindex.ai/) multi-agents project using [W
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, setup the environment with poetry:
|
||||
First, setup the environment with uv:
|
||||
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```shell
|
||||
poetry install
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory.
|
||||
@@ -16,13 +16,13 @@ Make sure you have set the `OPENAI_API_KEY` for the LLM and the `E2B_API_KEY` fo
|
||||
Second, generate the embeddings of the documents in the `./data` directory:
|
||||
|
||||
```shell
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, run the development server:
|
||||
|
||||
```shell
|
||||
poetry run dev
|
||||
uv run fastapi dev
|
||||
```
|
||||
|
||||
Then open [http://localhost:8000](http://localhost:8000) with your browser to start the chat UI.
|
||||
@@ -30,7 +30,7 @@ Then open [http://localhost:8000](http://localhost:8000) with your browser to st
|
||||
To start the app optimized for **production**, run:
|
||||
|
||||
```
|
||||
poetry run prod
|
||||
uv run fastapi run
|
||||
```
|
||||
|
||||
## Configure LLM and Embedding Model
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from app.settings import init_settings
|
||||
from app.workflow import create_workflow
|
||||
@@ -14,18 +12,15 @@ COMPONENT_DIR = "components"
|
||||
|
||||
|
||||
def create_app():
|
||||
env = os.environ.get("APP_ENV")
|
||||
|
||||
app = LlamaIndexServer(
|
||||
workflow_factory=create_workflow, # A factory function that creates a new workflow for each request
|
||||
ui_config=UIConfig(
|
||||
component_dir=COMPONENT_DIR,
|
||||
app_title="Chat App",
|
||||
),
|
||||
env=env,
|
||||
logger=logger,
|
||||
)
|
||||
# You can also add custom routes to the app
|
||||
# You can also add custom FastAPI routes to app
|
||||
app.add_api_route("/api/health", lambda: {"message": "OK"}, status_code=200)
|
||||
return app
|
||||
|
||||
@@ -33,14 +28,3 @@ def create_app():
|
||||
load_dotenv()
|
||||
init_settings()
|
||||
app = create_app()
|
||||
|
||||
|
||||
def run(env: str):
|
||||
os.environ["APP_ENV"] = env
|
||||
app_host = os.getenv("APP_HOST", "0.0.0.0")
|
||||
app_port = os.getenv("APP_PORT", "8000")
|
||||
|
||||
if env == "dev":
|
||||
subprocess.run(["fastapi", "dev", "--host", app_host, "--port", app_port])
|
||||
else:
|
||||
subprocess.run(["fastapi", "run", "--host", app_host, "--port", app_port])
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
[tool]
|
||||
[tool.poetry]
|
||||
[project]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Marcus Schiesser <mail@marcusschiesser.de>"]
|
||||
authors = [
|
||||
{ name = "Marcus Schiesser", email = "mail@marcusschiesser.de" }
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11,<3.14"
|
||||
dependencies = [
|
||||
"python-dotenv>=1.0.0,<2.0.0",
|
||||
"pydantic<2.10",
|
||||
"aiostream>=0.5.2,<0.6.0",
|
||||
"llama-index-core>=0.12.28,<0.13.0",
|
||||
"llama-index-server>=0.1.14,<0.2.0",
|
||||
]
|
||||
|
||||
[tool.poetry.scripts]
|
||||
"generate" = "generate:generate_index"
|
||||
"generate:index" = "generate:generate_index"
|
||||
"generate:ui" = "generate:generate_ui_for_workflow"
|
||||
dev = "main:run('dev')"
|
||||
prod = "main:run('prod')"
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"mypy>=1.8.0,<2.0.0",
|
||||
"pytest>=8.3.5,<9.0.0",
|
||||
"pytest-asyncio>=0.25.3,<0.26.0",
|
||||
]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.11,<3.14"
|
||||
python-dotenv = "^1.0.0"
|
||||
pydantic = "<2.10"
|
||||
aiostream = "^0.5.2"
|
||||
llama-index-core = "^0.12.28"
|
||||
llama-index-server = "^0.1.14"
|
||||
[project.scripts]
|
||||
generate = "generate:generate_index"
|
||||
generate_index = "generate:generate_index"
|
||||
generate_ui = "generate:generate_ui_for_workflow"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
mypy = "^1.8.0"
|
||||
pytest = "^8.3.5"
|
||||
pytest-asyncio = "^0.25.3"
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.11"
|
||||
plugins = "pydantic.mypy"
|
||||
exclude = ["tests", "venv", ".venv", "output", "config"]
|
||||
exclude = [ "tests", "venv", ".venv", "output", "config" ]
|
||||
check_untyped_defs = true
|
||||
warn_unused_ignores = false
|
||||
show_error_codes = true
|
||||
@@ -38,12 +40,12 @@ ignore_missing_imports = true
|
||||
follow_imports = "silent"
|
||||
implicit_optional = true
|
||||
strict_optional = false
|
||||
disable_error_code = ["return-value", "assignment"]
|
||||
disable_error_code = [ "return-value", "assignment" ]
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "app.*"
|
||||
ignore_missing_imports = false
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
requires = [ "hatchling>=1.24" ]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
@@ -14,7 +14,7 @@ def get_query_engine(output_cls):
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=str(
|
||||
"StorageContext is empty - call 'poetry run generate' to generate the storage first"
|
||||
"StorageContext is empty - call 'uv run generate' to generate the storage first"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ fly apps open
|
||||
If you're having documents in the `./data` folder, run the following command to generate vector embeddings of the documents:
|
||||
|
||||
```
|
||||
fly console --machine <machine_id> --command "poetry run generate"
|
||||
fly console --machine <machine_id> --command "uv run generate"
|
||||
```
|
||||
|
||||
Where `machine_id` is the ID of the machine where the app is running. You can show the running machines with the `fly machines` command.
|
||||
@@ -67,7 +67,7 @@ docker run \
|
||||
-v $(pwd)/data:/app/data \ # Use your local folder to read the data
|
||||
-v $(pwd)/storage:/app/storage \ # Use your file system to store the vector database
|
||||
<your_image_name> \
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
The app will then be able to answer questions about the documents in the `./data` folder.
|
||||
|
||||
@@ -13,38 +13,31 @@ RUN npm install && npm run build
|
||||
# ====================================
|
||||
# Backend
|
||||
# ====================================
|
||||
FROM python:3.11 AS build
|
||||
FROM python:3.11 AS release
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV PYTHONPATH=/app
|
||||
|
||||
# Install Poetry
|
||||
RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python && \
|
||||
cd /usr/local/bin && \
|
||||
ln -s /opt/poetry/bin/poetry && \
|
||||
poetry config virtualenvs.create false
|
||||
# Install Astral uv
|
||||
# Download the latest installer
|
||||
ADD https://astral.sh/uv/install.sh /uv-installer.sh
|
||||
|
||||
# Install Chromium for web loader
|
||||
# Can disable this if you don't use the web loader to reduce the image size
|
||||
RUN apt update && apt install -y chromium chromium-driver
|
||||
RUN sh /uv-installer.sh && rm /uv-installer.sh
|
||||
|
||||
# Install dependencies
|
||||
COPY ./pyproject.toml ./poetry.lock* /app/
|
||||
RUN poetry install --no-root --no-cache --only main
|
||||
ENV PATH="/root/.local/bin/:$PATH"
|
||||
|
||||
# ====================================
|
||||
# Release
|
||||
# ====================================
|
||||
FROM build AS release
|
||||
|
||||
COPY --from=frontend /app/frontend/out /app/static
|
||||
|
||||
COPY . .
|
||||
|
||||
# Install dependencies
|
||||
RUN uv sync
|
||||
|
||||
# Remove frontend code
|
||||
RUN rm -rf .frontend
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["poetry", "run", "prod"]
|
||||
CMD ["uv", "run", "fastapi", "run"]
|
||||
@@ -7,8 +7,7 @@ First, setup the environment with poetry:
|
||||
> **_Note:_** This step is not needed if you are using the dev-container.
|
||||
|
||||
```
|
||||
poetry install
|
||||
poetry shell
|
||||
uv sync
|
||||
```
|
||||
|
||||
Then check the parameters that have been pre-configured in the `.env` file in this directory. (E.g. you might need to configure an `OPENAI_API_KEY` if you're using OpenAI as model provider).
|
||||
@@ -18,13 +17,13 @@ If you are using any tools or data sources, you can update their config files in
|
||||
Second, generate the embeddings of the documents in the `./data` directory:
|
||||
|
||||
```
|
||||
poetry run generate
|
||||
uv run generate
|
||||
```
|
||||
|
||||
Third, run the app:
|
||||
|
||||
```
|
||||
poetry run dev
|
||||
uv run dev
|
||||
```
|
||||
|
||||
Open [http://localhost:8000](http://localhost:8000) with your browser to start the app.
|
||||
@@ -55,7 +54,7 @@ You can start editing the API endpoints by modifying `app/api/routers/chat.py`.
|
||||
To start the app optimized for **production**, run:
|
||||
|
||||
```
|
||||
poetry run prod
|
||||
uv run prod
|
||||
```
|
||||
|
||||
## Deployments
|
||||
|
||||
@@ -1,33 +1,39 @@
|
||||
[tool.poetry]
|
||||
[project]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Marcus Schiesser <mail@marcusschiesser.de>"]
|
||||
authors = [
|
||||
{ name = "Marcus Schiesser", email = "mail@marcusschiesser.de" }
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11,<3.14"
|
||||
dependencies = [
|
||||
"llama-index>=0.12.1",
|
||||
"fastapi[standard]>=0.109.1",
|
||||
"uvicorn>=0.23.2",
|
||||
"python-dotenv>=1.0.0",
|
||||
"pydantic>=2.10",
|
||||
"aiostream>=0.5.2",
|
||||
"cachetools>=5.3.3",
|
||||
"rich>=13.9.4",
|
||||
]
|
||||
|
||||
[tool.poetry.scripts]
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"mypy>=1.8.0",
|
||||
"pytest>=8.3.5",
|
||||
"pytest-asyncio>=0.25.3",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
generate = "app.engine.generate:generate_datasource"
|
||||
dev = "run:dev" # Starts the app in dev mode
|
||||
prod = "run:prod" # Starts the app in prod mode
|
||||
build = "run:build" # Builds the frontend assets and copies them to the static directory
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.11,<3.14"
|
||||
fastapi = "^0.109.1"
|
||||
uvicorn = { extras = ["standard"], version = "^0.23.2" }
|
||||
python-dotenv = "^1.0.0"
|
||||
pydantic = "<2.10"
|
||||
aiostream = "^0.5.2"
|
||||
cachetools = "^5.3.3"
|
||||
llama-index = "^0.12.1"
|
||||
rich = "^13.9.4"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
mypy = "^1.8.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
requires = [ "hatchling>=1.24" ]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.11"
|
||||
|
||||
@@ -65,7 +65,7 @@ def build():
|
||||
|
||||
rich.print(
|
||||
"\n[bold]Built frontend successfully![/bold]"
|
||||
"\n[bold]Run: 'poetry run prod' to start the app[/bold]"
|
||||
"\n[bold]Run: 'uv run prod' to start the app[/bold]"
|
||||
"\n[bold]Don't forget to update the .env file![/bold]"
|
||||
)
|
||||
except CalledProcessError as e:
|
||||
@@ -205,16 +205,16 @@ async def _run_backend(
|
||||
f"Port {APP_PORT} is not available! Please change the port in .env file or kill the process running on this port."
|
||||
)
|
||||
rich.print(f"\n[bold]Starting app on port {APP_PORT}...[/bold]")
|
||||
poetry_executable = _get_poetry_executable()
|
||||
uv_executable = _get_uv_executable()
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
poetry_executable,
|
||||
uv_executable,
|
||||
"run",
|
||||
"python",
|
||||
"main.py",
|
||||
env=envs,
|
||||
)
|
||||
# Wait for port is started
|
||||
timeout = 30
|
||||
timeout = 60
|
||||
for _ in range(timeout):
|
||||
await asyncio.sleep(1)
|
||||
if process.returncode is not None:
|
||||
@@ -265,21 +265,21 @@ def _get_node_package_manager() -> NodePackageManager:
|
||||
)
|
||||
|
||||
|
||||
def _get_poetry_executable() -> str:
|
||||
def _get_uv_executable() -> str:
|
||||
"""
|
||||
Check for available Poetry executables and return the preferred one.
|
||||
Returns 'poetry' if installed, falls back to 'poetry.cmd'.
|
||||
Check for available UV executables and return the preferred one.
|
||||
Returns 'uv' if installed, falls back to 'uv.cmd'.
|
||||
Raises SystemError if neither is installed.
|
||||
|
||||
Returns:
|
||||
str: The full path to the available Poetry executable
|
||||
str: The full path to the available UV executable
|
||||
"""
|
||||
poetry_cmds = ["poetry", "poetry.cmd"]
|
||||
for cmd in poetry_cmds:
|
||||
uv_cmds = ["uv", "uv.cmd"]
|
||||
for cmd in uv_cmds:
|
||||
cmd_path = which(cmd)
|
||||
if cmd_path is not None:
|
||||
return cmd_path
|
||||
raise SystemError("Poetry is not installed. Please install Poetry first.")
|
||||
raise SystemError("uv is not installed. Please install uv first.")
|
||||
|
||||
|
||||
def _is_port_available(port: int) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user