Compare commits

..

62 Commits

Author SHA1 Message Date
github-actions[bot] 7711216134 Release 0.5.11 (#582)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-28 14:48:28 +07:00
Marcus Schiesser 93d601972e docs: fix llamaindexserver 2025-04-28 14:46:55 +07:00
Thuc Pham 8fe5fc24c1 chore: add llamaindex server package (#585) 2025-04-28 14:37:12 +07:00
Thuc Pham 3960618454 chore: create-llama monorepo (#581)
* chore: create-llama monorepo

* add root package.json and pnpm workspace

* keep e2e inside create-llama

* update root package.json

* move scripts and dev dependencies of create-llama to root

* update e2e test for create-llama package

* update lint workflow

* update release llama-index-server workflow

* update path for test_llama_index_server workflow

* remove local lock file

* keep lint and format in create-llama

* fix: format

* update pre-commit

* move playwright back to create-llama

* disable pnpm for installing generated frontend

* use npm for type check

* update gitignore

* try --ignore-workspace option

* Move llama-index-server from packages/python-server to python directory

* update CI for python server

* Create plenty-spies-tickle.md
2025-04-25 18:38:02 +07:00
github-actions[bot] 53e1cd56e7 Release 0.5.10 (#579)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-22 15:45:31 +07:00
Huu Le 0a2e12a2bb Use uv as the default package manager and deprecate poetry. (#578) 2025-04-22 15:44:11 +07:00
github-actions[bot] 2e536dca36 Release 0.5.9 (#577)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-18 19:35:10 +07:00
Huu Le 4bc53ac24e feat: support UI generator for TS (#566) 2025-04-18 19:14:29 +07:00
github-actions[bot] 2deb63a6cc chore(release): bump version to 0.1.14 (#567)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-18 17:54:50 +07:00
github-actions[bot] 2ffa057f77 Release 0.5.8 (#573)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-18 17:51:19 +07:00
Huu Le 64f151dd66 bump chat ui (#575) 2025-04-18 17:43:22 +07:00
Thuc Pham 765181adb0 chore: test typescript e2e with node 20 and 22 (#572)
* chore: test typescript e2e with node 20 and 22

* Create sixty-chefs-search.md
2025-04-17 10:06:35 +02:00
github-actions[bot] 95c35e8a5c Release 0.5.7 (#571)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-17 13:51:52 +07:00
Thuc Pham 598865768a chore: bump llmaindex (#570) 2025-04-17 13:49:53 +07:00
github-actions[bot] 05453d55bf Release 0.5.6 (#569)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-16 20:40:15 +07:00
Huu Le d363ced4d8 bump llamaindex server package versions to 0.1.13 (python) and 0.1.3 (ts) (#568) 2025-04-16 20:38:58 +07:00
github-actions[bot] 293c6f97c1 chore(release): bump version to 0.1.13 (#561)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-16 16:29:41 +07:00
Huu Le 44b4d89ac1 Update document link and fix import (#565) 2025-04-16 16:23:17 +07:00
github-actions[bot] 60f10c5b5d Release 0.5.5 (#564)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-15 20:55:53 +07:00
Huu Le ee85320701 fix: missing default export (#563) 2025-04-15 20:54:23 +07:00
github-actions[bot] b12dc6f1e8 Release 0.5.4 (#562)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-15 18:28:11 +07:00
Huu Le 7c3b279417 support code generation of event components using an LLM (Python) (#557)
---------
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2025-04-15 18:23:06 +07:00
github-actions[bot] 1514a555d5 chore(release): bump version to 0.1.12 (#559)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-15 17:32:13 +07:00
Huu Le cddb4f6bcc chore: bump chat UI version to 0.1.2 and rename generate_ui_for_workflow (#560)
* chore: bump chat UI version to 0.1.2 and rename generate_ui_for_workflow

* feat: add exports for event component generation in gen_ui module

* update document

* refine prompt
2025-04-15 17:27:22 +07:00
github-actions[bot] c82e4f5791 chore(release): bump version to 0.1.11 (#555)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-15 13:11:15 +07:00
Huu Le 1f7e0e3c69 add GenUIWorkflow for generating UI components from workflow events (#549)
* feat: add GenUIWorkflow for generating UI components from workflow events

* feat: enhance GenUIWorkflow to support event handling and UI generation

* add cache, split code

* use gemini model

* refactor: update GenUIWorkflow to use Anthropic model and add pre-run checks for API key and package installation

* feat: introduce PlanningEvent and enhance GenUIWorkflow for improved UI planning and aggregation function generation

* feat: add gen ui to llamaindexserver

* refactor: remove unused gen_ui.py file

* simplify

* update for tailwindcss

* simplify code and add document

* refine text

* feat: add UIEvent model and update exports in server module

* use default UIEvent

* fix wrong model, update template

* add missing doc

* fix linting

* revert change on template

* fix mypy

* disable e2e for the change from llama-index-server

* remove unused script entry from pyproject.toml and refine UI notice text in GenUIWorkflow

* update workflow, bump chat ui

* Refine GenUIWorkflow documentation and improve code structure notes; add llm parameter to generate_ui_for_workflow function.
2025-04-15 13:06:55 +07:00
github-actions[bot] 7997cdeb70 Release 0.5.3 (#556)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-10 19:08:02 +07:00
Huu Le 76ec3605e5 update templates to use new chat UI config (#553) 2025-04-10 19:03:06 +07:00
github-actions[bot] 5cfdec7d75 chore(release): bump version to 0.1.10 (#550)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-10 17:47:23 +07:00
Huu Le 3d1b15d515 fix encoding windows (#554) 2025-04-10 17:37:49 +07:00
Huu Le 392393af9e feat: Add config app title for python, enhance config parameter. (#540)
* Enhance LlamaIndexServer UI configuration

* bump version, add use llamacloud to chat ui config

* add changeset

* refactor: streamline UI configuration and component directory handling

* relock and fix test

* remove change set

* update docs

* fix wrong key name

* fix test

* bump chat ui

* improve docs
2025-04-10 16:45:20 +07:00
Marcus Schiesser 920beda8ad chore: use own DeepResearchEvent (#552) 2025-04-09 20:44:38 +07:00
github-actions[bot] e6f8add778 Release 0.5.2 (#551)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-09 19:40:36 +07:00
Huu Le c9f8f8d5f2 feat: Use custom component for deep research use case (#548) 2025-04-09 19:31:09 +07:00
github-actions[bot] 24eb7736ee chore(release): bump version to 0.1.9 (#545)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-09 19:01:03 +07:00
Huu Le 5fb27220f7 feat: Add componentDir for llama_index_sever (#547)
* init code for custom components

* change router name

* use jsx

* add custom components code

* revert change on create-llama

* fix mypy

* adding document for custom component

* Refactor component directory handling in LlamaIndexServer

* add file name in components response

* Enhance documentation

* fix mypy

* use tmp in test

* docs: word smithing

* Refactor component loading logic in CustomUI to prioritize TSX over JSX files and improve duplicate handling.

* bump chat ui

---------

Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2025-04-09 18:51:39 +07:00
github-actions[bot] 5caa3813f8 chore(release): bump version to 0.1.8 (#534)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-03 21:33:54 +07:00
github-actions[bot] bc95789a8d Release 0.5.1 (#544)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-03 15:25:09 +02:00
Huu Le 08b3e079e4 chore: simplify local index code (#537) 2025-04-03 14:21:50 +02:00
Huu Le 1876950f89 fix null embedding model name when create llamacloud index (#543) 2025-04-03 13:10:19 +02:00
ForgQi c7349b44c4 fix: bump llama-index-core to fix handle missing fields parameter in default_formatter (#542)
* fix: handle missing fields parameter in default_formatter to avoid runtime error

https://github.com/run-llama/llama_index/pull/18340

* relock packages

---------

Co-authored-by: leehuwuj <leehuwuj@gmail.com>
2025-04-03 16:35:51 +07:00
github-actions[bot] 4068618b2d Release 0.5.0 (#508)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-04-02 19:34:57 +07:00
Huu Le 54c9e2f95e Feature: Simplify app code using LlamaIndexServer (#529)
---------
Co-authored-by: thucpn <thucsh2@gmail.com>
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2025-04-02 19:31:06 +07:00
github-actions[bot] aec1173b71 chore(release): bump version to 0.1.7 (#531)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-02 17:50:01 +07:00
Huu Le 481663dd63 chore(release): bump CHAT_UI_VERSION to 0.0.6 (#533) 2025-04-02 17:35:58 +07:00
Huu Le 1ca7dd2e48 fix llamacloud api and markdown issue (#532) 2025-04-02 17:07:25 +07:00
github-actions[bot] 3d20990713 chore(release): bump version to 0.1.6 (#528)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-01 22:25:51 +07:00
Huu Le 8fb69cf807 feat: add llamacloud to llama_index_server (#530) 2025-04-01 22:23:34 +07:00
github-actions[bot] 61af56dac6 chore(release): bump version to 0.1.5 (#526)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-26 22:41:43 +07:00
Huu Le 4b66039a96 update variable (#527) 2025-03-26 22:40:34 +07:00
github-actions[bot] ee88f681a6 chore(release): bump version to 0.1.4 (#524)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-26 17:55:02 +07:00
Huu Le 992c3a95e9 update release workflow for llama-index-server (#525) 2025-03-26 17:53:33 +07:00
github-actions[bot] 2a4fb702d1 chore(release): bump version to 0.1.3 (#522)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-26 17:39:28 +07:00
Huu Le 24b9337096 fix: poetry release ci (#523)
* Fix unnecessary create PR and wrong PyPI environment name

* use JRubics/poetry-publish
2025-03-26 17:36:53 +07:00
github-actions[bot] fceec69a3a chore(release): release llama-index-server 0.1.2 (#520)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-26 17:10:54 +07:00
Huu Le 03e5e0a16e fix release ci, add --no-interaction (#521) 2025-03-26 17:09:16 +07:00
github-actions[bot] fe3cd36d3a chore(release): bump version to 0.1.1 (#517)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-03-26 16:55:29 +07:00
Huu Le d5d10e9ead Support overriding UI configuration for LlamaIndexServer (#519)
* support for ui config override

* remove dead code

* bump chat ui

* fix linting
2025-03-26 16:39:27 +07:00
Huu Le 5ed925d75f stream ToolCallResult event in agent tool utils (#518) 2025-03-26 13:38:50 +07:00
Huu Le ca5df14d41 feat: Add llama_index_sever (#516) 2025-03-25 20:59:52 +07:00
Thuc Pham ee69ce7cc1 bump: chat-ui and tailwind v4 (#509) 2025-02-25 09:38:31 +07:00
Thuc Pham 0e4ecfaf8b fix: add trycatch for generating error (#507) 2025-02-20 16:34:14 +07:00
573 changed files with 33176 additions and 2216 deletions
+27 -24
View File
@@ -1,12 +1,13 @@
name: E2E Tests
name: E2E Tests for create-llama package
on:
push:
branches: [main]
paths-ignore:
- "python/llama-index-server/**"
pull_request:
branches: [main]
env:
POETRY_VERSION: "1.6.1"
paths-ignore:
- "python/llama-index-server/**"
jobs:
e2e-python:
@@ -32,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
@@ -50,15 +51,15 @@ jobs:
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
working-directory: .
working-directory: packages/create-llama
- name: Build create-llama
run: pnpm run build
working-directory: .
working-directory: packages/create-llama
- name: Install
run: pnpm run pack-install
working-directory: .
working-directory: packages/create-llama
- name: Run Playwright tests for Python
run: pnpm run e2e:python
@@ -67,13 +68,15 @@ jobs:
LLAMA_CLOUD_API_KEY: ${{ secrets.LLAMA_CLOUD_API_KEY }}
FRAMEWORK: ${{ matrix.frameworks }}
DATASOURCE: ${{ matrix.datasources }}
working-directory: .
PYTHONIOENCODING: utf-8
PYTHONLEGACYWINDOWSSTDIO: utf-8
working-directory: packages/create-llama
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-python-${{ matrix.os }}-${{ matrix.frameworks }}-${{ matrix.datasources }}
path: ./playwright-report/
path: packages/create-llama/playwright-report/
overwrite: true
retention-days: 30
@@ -83,10 +86,10 @@ jobs:
strategy:
fail-fast: true
matrix:
node-version: [18, 20]
node-version: [20, 22]
python-version: ["3.11"]
os: [macos-latest, windows-latest, ubuntu-22.04]
frameworks: ["nextjs", "express"]
frameworks: ["nextjs"]
datasources: ["--no-files", "--example-file", "--llamacloud"]
defaults:
run:
@@ -100,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
@@ -118,15 +121,15 @@ jobs:
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
working-directory: .
working-directory: packages/create-llama
- name: Build create-llama
run: pnpm run build
working-directory: .
working-directory: packages/create-llama
- name: Install
run: pnpm run pack-install
working-directory: .
working-directory: packages/create-llama
- name: Run Playwright tests for TypeScript
run: pnpm run e2e:typescript
@@ -135,12 +138,12 @@ jobs:
LLAMA_CLOUD_API_KEY: ${{ secrets.LLAMA_CLOUD_API_KEY }}
FRAMEWORK: ${{ matrix.frameworks }}
DATASOURCE: ${{ matrix.datasources }}
working-directory: .
working-directory: packages/create-llama
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-typescript-${{ matrix.os }}-${{ matrix.frameworks }}-${{ matrix.datasources }}-node${{ matrix.node-version }}
path: ./playwright-report/
path: packages/create-llama/playwright-report/
overwrite: true
retention-days: 30
@@ -35,8 +35,10 @@ jobs:
uses: chartboost/ruff-action@v1
with:
args: "format --check"
src: "python/llama-index-server"
- name: Run Python lint
uses: chartboost/ruff-action@v1
with:
args: "check"
src: "python/llama-index-server"
@@ -0,0 +1,130 @@
name: Release llama-index-server
on:
push:
branches:
- main
paths:
- "python/llama-index-server/**"
- ".github/workflows/release_llama_index_server.yml"
pull_request:
types:
- closed
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Create Release PR
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./python/llama-index-server
if: |
github.event_name == 'push' &&
!startsWith(github.ref, 'refs/heads/release/llama-index-server-v')
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
- name: Install dependencies
run: poetry install
- name: Setup Git
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Bump patch version
run: |
poetry version patch
git add pyproject.toml
git commit -m "chore(release): bump version to $(poetry version -s)"
- name: Get current version
id: get_version
run: |
version=$(poetry version -s)
echo "current_version=${version}" >> "$GITHUB_OUTPUT"
- name: Create Release PR
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "Release: llama-index-server v${{ steps.get_version.outputs.current_version }}"
title: "Release: llama-index-server v${{ steps.get_version.outputs.current_version }}"
body: |
This PR was automatically created to release a new version of the llama-index-server package.
Version: ${{ steps.get_version.outputs.current_version }}
Please review the changes and merge to trigger the release.
branch: release/llama-index-server-v${{ steps.get_version.outputs.current_version }}
base: main
labels: release, llama-index-server
publish:
name: Publish to PyPI
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./python/llama-index-server
if: |
github.event_name == 'pull_request' &&
github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.title, 'Release: llama-index-server') &&
startsWith(github.event.pull_request.head.ref, 'release/llama-index-server-v')
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
- name: Install dependencies
run: poetry install
- name: Get current version
id: get_version
run: |
version=$(poetry version -s)
echo "current_version=${version}" >> "$GITHUB_OUTPUT"
- name: Build and publish to PyPI
uses: JRubics/poetry-publish@v2.1
with:
python_version: "3.11"
pypi_token: ${{ secrets.PYPI_TOKEN }}
package_directory: "python/llama-index-server"
poetry_install_options: "--without dev"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: llama-index-server-v${{ steps.get_version.outputs.current_version }}
name: "llama-index-server v${{ steps.get_version.outputs.current_version }}"
body: |
Release of llama-index-server v${{ steps.get_version.outputs.current_version }}
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,111 @@
name: Build Package
on:
pull_request:
env:
POETRY_VERSION: "1.8.3"
PYTHON_VERSION: "3.9"
jobs:
unit-test:
name: Unit Tests
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: python/llama-index-server
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.9"]
steps:
- uses: actions/checkout@v4
- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}
- name: Set up python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "poetry"
- name: Configure Poetry
run: |
poetry config virtualenvs.create true
poetry config virtualenvs.in-project true
poetry env use python
- name: Install dependencies
shell: bash
run: poetry install --with dev
- name: Run unit tests
shell: bash
run: |
poetry run pytest tests
type-check:
name: Type Check
runs-on: ubuntu-latest
defaults:
run:
working-directory: python/llama-index-server
steps:
- uses: actions/checkout@v4
- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: "poetry"
- name: Configure Poetry
run: |
poetry config virtualenvs.create true
poetry config virtualenvs.in-project true
poetry env use python
- name: Install dependencies
shell: bash
run: poetry install --with dev
- name: Run mypy
shell: bash
run: poetry run mypy llama_index
build:
needs: [unit-test, type-check]
runs-on: ubuntu-latest
defaults:
run:
working-directory: python/llama-index-server
steps:
- uses: actions/checkout@v4
- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Clear python cache
shell: bash
run: poetry cache clear --all pypi
- name: Build package
shell: bash
run: poetry build
- name: Test installing built package
shell: bash
run: python -m pip install .
- name: Test import
shell: bash
working-directory: ${{ vars.RUNNER_TEMP }}
run: python -c "from llama_index.server import LlamaIndexServer"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: llama-index-server
path: python/llama-index-server/dist/
-18
View File
@@ -6,9 +6,6 @@ node_modules
.pnpm-store
.pnp.js
# testing
coverage
# next.js
.next/
out/
@@ -34,24 +31,9 @@ yarn-error.log*
dist/
lib/
# e2e
.cache
test-results/
playwright-report/
blob-report/
playwright/.cache/
.tsbuildinfo
e2e/cache
# intellij
**/.idea
# Python
.mypy_cache/
# build artifacts
create-llama-*.tgz
# vscode
.vscode
!.vscode/settings.json
+1 -1
View File
@@ -1,3 +1,3 @@
pnpm format
pnpm lint
uvx ruff format --check templates/
uvx ruff format --check packages/create-llama/templates/
+8 -1
View File
@@ -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
@@ -130,4 +130,11 @@ Pro mode is ideal for developers who want fine-grained control over their projec
- [TS/JS docs](https://ts.llamaindex.ai/)
- [Python docs](https://docs.llamaindex.ai/en/stable/)
## LlamaIndex Server
The generated code is using the LlamaIndex Server, which serves LlamaIndex Workflows and Agent Workflows via an API server. See the following docs for more information:
- [LlamaIndex Server For TypeScript](./packages/server/README.md)
- [LlamaIndex Server For Python](./python/llama-index-server/README.md)
Inspired by and adapted from [create-next-app](https://github.com/vercel/next.js/tree/canary/packages/create-next-app)
+37 -84
View File
@@ -1,86 +1,39 @@
{
"name": "create-llama",
"version": "0.4.0",
"description": "Create LlamaIndex-powered apps with one command",
"keywords": [
"rag",
"llamaindex",
"next.js"
],
"repository": {
"type": "git",
"url": "https://github.com/run-llama/create-llama",
"directory": "packages/create-llama"
},
"license": "MIT",
"bin": {
"create-llama": "./dist/index.js"
},
"files": [
"dist"
],
"scripts": {
"build": "bash ./scripts/build.sh",
"build:ncc": "pnpm run clean && ncc build ./index.ts -o ./dist/ --minify --no-cache --no-source-map-register",
"clean": "rimraf --glob ./dist ./templates/**/__pycache__ ./templates/**/node_modules ./templates/**/poetry.lock",
"dev": "ncc build ./index.ts -w -o dist/",
"e2e": "playwright test",
"e2e:python": "playwright test e2e/shared e2e/python",
"e2e:typescript": "playwright test e2e/shared e2e/typescript",
"format": "prettier --ignore-unknown --cache --check .",
"format:write": "prettier --ignore-unknown --write .",
"lint": "eslint . --ignore-pattern dist --ignore-pattern e2e/cache",
"new-snapshot": "pnpm run build && changeset version --snapshot",
"new-version": "pnpm run build && changeset version",
"pack-install": "bash ./scripts/pack.sh",
"prepare": "husky",
"release": "pnpm run build && changeset publish",
"release-snapshot": "pnpm run build && changeset publish --tag snapshot"
},
"dependencies": {
"@types/async-retry": "1.4.2",
"@types/ci-info": "2.0.0",
"@types/cross-spawn": "6.0.0",
"@types/fs-extra": "11.0.4",
"@types/node": "^20.11.7",
"@types/prompts": "2.4.2",
"@types/tar": "6.1.5",
"@types/validate-npm-package-name": "3.0.0",
"async-retry": "1.3.1",
"async-sema": "3.0.1",
"ci-info": "github:watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540",
"commander": "12.1.0",
"cross-spawn": "7.0.3",
"fast-glob": "3.3.1",
"fs-extra": "11.2.0",
"global-agent": "^3.0.0",
"got": "10.7.0",
"ollama": "^0.5.0",
"ora": "^8.0.1",
"picocolors": "1.0.0",
"prompts": "2.4.2",
"smol-toml": "^1.1.4",
"tar": "6.1.15",
"terminal-link": "^3.0.0",
"update-check": "1.5.4",
"validate-npm-package-name": "3.0.0",
"yaml": "2.4.1"
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
"@playwright/test": "^1.41.1",
"@vercel/ncc": "0.38.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^8.10.0",
"husky": "^9.0.10",
"prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^3.2.4",
"rimraf": "^5.0.5",
"typescript": "^5.3.3",
"wait-port": "^1.1.0"
},
"packageManager": "pnpm@9.0.5",
"engines": {
"node": ">=16.14.0"
}
"name": "create-llama-monorepo",
"version": "1.0.0",
"private": true,
"description": "Monorepo for create-llama",
"keywords": [
"rag",
"llamaindex"
],
"repository": {
"type": "git",
"url": "https://github.com/run-llama/create-llama"
},
"license": "MIT",
"workspaces": [
"packages/*"
],
"scripts": {
"prepare": "husky",
"new-snapshot": "pnpm -r build && changeset version --snapshot",
"new-version": "pnpm -r build && changeset version",
"release": "pnpm -r build && changeset publish",
"release-snapshot": "pnpm -r build && changeset publish --tag snapshot",
"build": "pnpm -r build",
"e2e": "pnpm -r e2e",
"dev": "pnpm -r dev",
"format": "pnpm -r format",
"format:write": "pnpm -r format:write",
"lint": "pnpm -r lint"
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
"husky": "^9.0.10"
},
"packageManager": "pnpm@9.0.5",
"engines": {
"node": ">=16.14.0"
}
}
+65
View File
@@ -0,0 +1,65 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
node_modules
.pnp
.pnpm-store
.pnp.js
# testing
coverage
.coverage
# next.js
.next/
out/
build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# build
dist/
lib/
# e2e
.cache
test-results/
playwright-report/
blob-report/
playwright/.cache/
.tsbuildinfo
e2e/cache
# intellij
**/.idea
# Python
.mypy_cache/
venv/
.venv/
dist/
.__pycache__
__pycache__
.python-version
.ui
# build artifacts
create-llama-*.tgz
# copied from root
README.md
LICENSE.md
@@ -1,5 +1,84 @@
# create-llama
## 0.5.11
### Patch Changes
- 3960618: chore: create-llama monorepo
- 8fe5fc2: chore: add llamaindex server package
## 0.5.10
### Patch Changes
- 0a2e12a: Use uv as the default package manager
## 0.5.9
### Patch Changes
- 4bc53ac: Bump new chat ui and update deep research component
- 4bc53ac: Support generate UI for deep research use case (Typescript)
## 0.5.8
### Patch Changes
- 765181a: chore: test typescript e2e with node 20 and 22
## 0.5.7
### Patch Changes
- 5988657: chore: bump llmaindex
## 0.5.6
### Patch Changes
- d363ced: Bump llamaindex server packages
## 0.5.5
### Patch Changes
- ee85320: The default custom deep research component does not work.
## 0.5.4
### Patch Changes
- 7c3b279: Support code generation of event components using an LLM (Python)
## 0.5.3
### Patch Changes
- 76ec360: Update templates to use new chat ui config
## 0.5.2
### Patch Changes
- c9f8f8d: Use custom component for deep research use case
## 0.5.1
### Patch Changes
- 08b3e07: Simplify the local index code.
## 0.5.0
### Minor Changes
- 54c9e2f: Simplified generated code using LlamaIndexServer
### Patch Changes
- 0e4ecfa: fix: add trycatch for generating error
- ee69ce7: bump: chat-ui and tailwind v4
## 0.4.0
### Minor Changes
@@ -90,7 +90,7 @@ export async function createApp({
// Install backend
await installTemplate({ ...args, backend: true });
if (frontend && framework === "fastapi") {
if (frontend && framework === "fastapi" && template !== "llamaindexserver") {
// install frontend
const frontendRoot = path.join(root, ".frontend");
await makeDir(frontendRoot);
@@ -110,7 +110,7 @@ export async function createApp({
console.log();
}
if (toolsRequireConfig(tools)) {
if (toolsRequireConfig(tools) && template !== "llamaindexserver") {
const configFile =
framework === "fastapi" ? "config/tools.yaml" : "config/tools.json";
console.log(
@@ -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;
@@ -16,15 +16,17 @@ const templateFramework: TemplateFramework = process.env.FRAMEWORK
const dataSource: string = "--example-file";
const templateUI: TemplateUI = "shadcn";
const templatePostInstallAction: TemplatePostInstallAction = "runApp";
const appType: AppType = templateFramework === "fastapi" ? "--frontend" : "";
const appType: AppType = "--frontend";
const userMessage = "Write a blog post about physical standards for letters";
const templateUseCases = ["financial_report", "blog", "form_filling"];
const templateUseCases = ["financial_report", "agentic_rag", "deep_research"];
for (const useCase of templateUseCases) {
test.describe(`Test multiagent template ${useCase} ${templateFramework} ${dataSource} ${templateUI} ${appType} ${templatePostInstallAction}`, async () => {
test.describe(`Test use case ${useCase} ${templateFramework} ${dataSource} ${templateUI} ${appType} ${templatePostInstallAction}`, async () => {
test.skip(
process.platform !== "linux" || process.env.DATASOURCE === "--no-files",
"The multiagent template currently only works with files. We also only run on Linux to speed up tests.",
process.platform !== "linux" ||
process.env.DATASOURCE === "--no-files" ||
templateFramework === "express",
"The llamaindexserver template currently only works with nextjs, fastapi. We also only run on Linux to speed up tests.",
);
let port: number;
let cwd: string;
@@ -38,7 +40,7 @@ for (const useCase of templateUseCases) {
cwd = await createTestDir();
const result = await runCreateLlama({
cwd,
templateType: "multiagent",
templateType: "llamaindexserver",
templateFramework,
dataSource,
vectorDb,
@@ -63,7 +65,9 @@ for (const useCase of templateUseCases) {
templateFramework === "express",
);
await page.goto(`http://localhost:${port}`);
await expect(page.getByText("Built by LlamaIndex")).toBeVisible();
await expect(page.getByText("Built by LlamaIndex")).toBeVisible({
timeout: 5 * 60 * 1000,
});
});
test("Frontend should be able to submit a message and receive the start of a streamed response", async ({
@@ -72,9 +76,9 @@ for (const useCase of templateUseCases) {
test.skip(
templatePostInstallAction !== "runApp" ||
useCase === "financial_report" ||
useCase === "form_filling" ||
useCase === "deep_research" ||
templateFramework === "express",
"Skip chat tests for financial report and form filling.",
"Skip chat tests for financial report and deep research.",
);
await page.goto(`http://localhost:${port}`);
await page.fill("form textarea", userMessage);
@@ -86,6 +90,12 @@ for (const useCase of templateUseCases) {
await page.click("form button[type=submit]");
const response = await responsePromise;
console.log(`Response status: ${response.status()}`);
const responseBody = await response
.text()
.catch((e) => `Error reading body: ${e}`);
console.log(`Response body: ${responseBody}`);
expect(response.ok()).toBeTruthy();
});
@@ -74,7 +74,7 @@ test.describe("Test resolve TS dependencies", () => {
// Install dependencies using pnpm
try {
const { stderr: installStderr } = await execAsync(
"pnpm install --prefer-offline",
"pnpm install --prefer-offline --ignore-workspace",
{
cwd: appDir,
},
@@ -113,7 +113,12 @@ export async function runCreateLlama({
if (observability) {
commandArgs.push("--observability", observability);
}
if ((templateType === "multiagent" || templateType === "reflex") && useCase) {
if (
(templateType === "multiagent" ||
templateType === "reflex" ||
templateType === "llamaindexserver") &&
useCase
) {
commandArgs.push("--use-case", useCase);
}
@@ -44,6 +44,7 @@ const renderEnvVar = (envVars: EnvVar[]): string => {
const getVectorDBEnvs = (
vectorDb?: TemplateVectorDB,
framework?: TemplateFramework,
template?: TemplateType,
): EnvVar[] => {
if (!vectorDb || !framework) {
return [];
@@ -168,7 +169,7 @@ const getVectorDBEnvs = (
description:
"The organization ID for the LlamaCloud project (uses default organization if not specified)",
},
...(framework === "nextjs"
...(framework === "nextjs" && template !== "llamaindexserver"
? // activate index selector per default (not needed for non-NextJS backends as it's handled by createFrontendEnvFile)
[
{
@@ -223,13 +224,15 @@ Otherwise, use CHROMA_HOST and CHROMA_PORT config above`,
},
];
default:
return [
{
name: "STORAGE_CACHE_DIR",
description: "The directory to store the local storage cache.",
value: ".cache",
},
];
return template !== "llamaindexserver"
? [
{
name: "STORAGE_CACHE_DIR",
description: "The directory to store the local storage cache.",
value: ".cache",
},
]
: [];
}
};
@@ -382,38 +385,42 @@ const getModelEnvs = (modelConfig: ModelConfig): EnvVar[] => {
const getFrameworkEnvs = (
framework: TemplateFramework,
template: TemplateType,
port?: number,
): EnvVar[] => {
const sPort = port?.toString() || "8000";
const result: EnvVar[] = [
{
name: "FILESERVER_URL_PREFIX",
description:
"FILESERVER_URL_PREFIX is the URL prefix of the server storing the images generated by the interpreter.",
value:
framework === "nextjs"
? // FIXME: if we are using nextjs, port should be 3000
"http://localhost:3000/api/files"
: `http://localhost:${sPort}/api/files`,
},
];
const result: EnvVar[] =
template !== "llamaindexserver"
? [
{
name: "FILESERVER_URL_PREFIX",
description:
"FILESERVER_URL_PREFIX is the URL prefix of the server storing the images generated by the interpreter.",
value:
framework === "nextjs"
? // FIXME: if we are using nextjs, port should be 3000
"http://localhost:3000/api/files"
: `http://localhost:${sPort}/api/files`,
},
]
: [];
if (framework === "fastapi") {
result.push(
...[
{
name: "APP_HOST",
description: "The address to start the backend app.",
description: "The address to start the FastAPI app.",
value: "0.0.0.0",
},
{
name: "APP_PORT",
description: "The port to start the backend app.",
description: "The port to start the FastAPI app.",
value: sPort,
},
],
);
}
if (framework === "nextjs") {
if (framework === "nextjs" && template !== "llamaindexserver") {
result.push({
name: "NEXT_PUBLIC_CHAT_API",
description:
@@ -569,25 +576,41 @@ export const createBackendEnvFile = async (
| "port"
| "tools"
| "observability"
| "useLlamaParse"
>,
) => {
// Init env values
const envFileName = ".env";
const envVars: EnvVar[] = [
{
name: "LLAMA_CLOUD_API_KEY",
description: `The Llama Cloud API key.`,
value: opts.llamaCloudKey,
},
// Add environment variables of each component
...getModelEnvs(opts.modelConfig),
...getEngineEnvs(),
...getVectorDBEnvs(opts.vectorDb, opts.framework),
...getFrameworkEnvs(opts.framework, opts.port),
...(opts.useLlamaParse
? [
{
name: "LLAMA_CLOUD_API_KEY",
description: `The Llama Cloud API key.`,
value: opts.llamaCloudKey,
},
]
: []),
...getVectorDBEnvs(opts.vectorDb, opts.framework, opts.template),
...getToolEnvs(opts.tools),
...getTemplateEnvs(opts.template),
...getObservabilityEnvs(opts.observability),
...getSystemPromptEnv(opts.tools, opts.dataSources, opts.template),
...getFrameworkEnvs(opts.framework, opts.template, opts.port),
// Add environment variables of each component
...(opts.template === "llamaindexserver"
? [
{
name: "OPENAI_API_KEY",
description: "The OpenAI API key to use.",
value: opts.modelConfig.apiKey,
},
]
: [
// don't use this stuff for llama-indexserver
...getModelEnvs(opts.modelConfig),
...getEngineEnvs(),
...getTemplateEnvs(opts.template),
...getObservabilityEnvs(opts.observability),
...getSystemPromptEnv(opts.tools, opts.dataSources, opts.template),
]),
];
// Render and write env file
const content = renderEnvVar(envVars);
@@ -1,7 +1,7 @@
import { callPackageManager } from "./install";
import path from "path";
import { cyan } from "picocolors";
import picocolors, { cyan } from "picocolors";
import fsExtra from "fs-extra";
import { writeLoadersConfig } from "./datasources";
@@ -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,
@@ -41,7 +41,11 @@ const checkForGenerateScript = (
missingSettings.push("your LLAMA_CLOUD_API_KEY");
}
if (vectorDb !== "none" && vectorDb !== "llamacloud") {
if (
vectorDb !== undefined &&
vectorDb !== "none" &&
vectorDb !== "llamacloud"
) {
missingSettings.push("your Vector DB environment variables");
}
@@ -60,7 +64,7 @@ async function generateContextData(
if (packageManager) {
const runGenerate = `${cyan(
framework === "fastapi"
? "poetry run generate"
? "uv run generate"
: `${packageManager} run generate`,
)}`;
@@ -74,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.`);
@@ -92,14 +102,14 @@ async function generateContextData(
}
const settingsMessage = `After setting ${missingSettings.join(" and ")}, run ${runGenerate} to generate the context data.`;
console.log(`\n${settingsMessage}\n\n`);
console.log(picocolors.yellow(`\n${settingsMessage}\n\n`));
}
}
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 (
@@ -166,6 +176,17 @@ export const installTemplate = async (
if (props.framework === "fastapi") {
await installPythonTemplate(props);
} else {
await installTSTemplate(props);
}
// write configurations
if (props.template !== "llamaindexserver") {
await writeToolsConfig(
props.root,
props.tools,
props.framework === "fastapi" ? ConfigFileType.YAML : ConfigFileType.JSON,
);
if (props.vectorDb !== "llamacloud") {
// write loaders configuration (currently Python only)
// not needed for LlamaCloud as it has its own loaders
@@ -175,26 +196,13 @@ export const installTemplate = async (
props.useLlamaParse,
);
}
} else {
await installTSTemplate(props);
}
// write tools configuration
await writeToolsConfig(
props.root,
props.tools,
props.framework === "fastapi" ? ConfigFileType.YAML : ConfigFileType.JSON,
);
if (props.backend) {
// This is a backend, so we need to copy the test data and create the env file.
// Copy the environment file to the target directory.
if (
props.template === "streaming" ||
props.template === "multiagent" ||
props.template === "reflex"
) {
if (props.template !== "community" && props.template !== "llamapack") {
await createBackendEnvFile(props.root, props);
}
@@ -143,6 +143,6 @@ export const installLlamapackProject = async ({
await copyData({ root });
await installLlamapackExample({ root, llamapack });
if (postInstallAction === "runApp" || postInstallAction === "dependencies") {
installPythonDependencies({ noRoot: true });
installPythonDependencies();
}
};
@@ -3,15 +3,16 @@ 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,
ModelConfig,
TemplateDataSource,
TemplateObservability,
TemplateType,
TemplateVectorDB,
} from "./types";
@@ -29,6 +30,7 @@ const getAdditionalDependencies = (
dataSources?: TemplateDataSource[],
tools?: Tool[],
templateType?: TemplateType,
observability?: TemplateObservability,
) => {
const dependencies: Dependency[] = [];
@@ -37,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",
},
@@ -61,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",
},
@@ -89,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;
}
@@ -116,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;
}
@@ -156,155 +158,122 @@ 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;
}
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 };
if (observability && observability !== "none") {
if (observability === "traceloop") {
dependencies.push({
name: "traceloop-sdk",
version: ">=0.15.11,<0.16.0",
});
}
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;
if (observability === "llamatrace") {
dependencies.push({
name: "llama-index-callbacks-arize-phoenix",
version: ">=0.3.0,<0.4.0",
});
}
}
return dependencies;
};
const copyRouterCode = async (root: string, tools: Tool[]) => {
@@ -329,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`,
@@ -350,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);
@@ -369,57 +417,34 @@ 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);
}
};
export const installPythonTemplate = async ({
appName,
const installLegacyPythonTemplate = async ({
root,
template,
framework,
vectorDb,
postInstallAction,
modelConfig,
dataSources,
tools,
useLlamaParse,
useCase,
observability,
}: Pick<
InstallTemplateArgs,
| "appName"
| "root"
| "template"
| "framework"
| "vectorDb"
| "postInstallAction"
| "modelConfig"
| "dataSources"
| "tools"
| "useLlamaParse"
| "useCase"
| "observability"
>) => {
console.log("\nInitializing Python project with template:", template, "\n");
let templatePath;
if (template === "reflex") {
templatePath = path.join(templatesDir, "types", "reflex");
} else {
templatePath = path.join(templatesDir, "types", "streaming", framework);
}
await copy("**", root, {
parents: true,
cwd: templatePath,
rename: assetRelocator,
});
const compPath = path.join(templatesDir, "components");
const enginePath = path.join(root, "app", "engine");
@@ -509,34 +534,7 @@ export const installPythonTemplate = async ({
}
}
console.log("Adding additional dependencies");
const addOnDependencies = getAdditionalDependencies(
modelConfig,
vectorDb,
dataSources,
tools,
template,
);
if (observability && observability !== "none") {
if (observability === "traceloop") {
addOnDependencies.push({
name: "traceloop-sdk",
version: "^0.15.11",
});
}
if (observability === "llamatrace") {
addOnDependencies.push({
name: "llama-index-callbacks-arize-phoenix",
version: "^0.3.0",
constraints: {
python: ">=3.11,<3.13",
},
});
}
const templateObservabilityPath = path.join(
templatesDir,
"components",
@@ -548,6 +546,133 @@ export const installPythonTemplate = async ({
cwd: templateObservabilityPath,
});
}
};
const installLlamaIndexServerTemplate = async ({
root,
useCase,
useLlamaParse,
}: Pick<InstallTemplateArgs, "root" | "useCase" | "useLlamaParse">) => {
if (!useCase) {
console.log(
red(
`There is no use case selected. Please pick a use case to use via --use-case flag.`,
),
);
process.exit(1);
}
await copy("workflow.py", path.join(root, "app"), {
parents: true,
cwd: path.join(templatesDir, "components", "workflows", "python", useCase),
});
// Copy custom UI component code
await copy(`*`, path.join(root, "components"), {
parents: true,
cwd: path.join(templatesDir, "components", "ui", "workflows", useCase),
});
if (useLlamaParse) {
await copy("index.py", path.join(root, "app"), {
parents: true,
cwd: path.join(
templatesDir,
"components",
"vectordbs",
"llamaindexserver",
"llamacloud",
"python",
),
});
// TODO: Consider moving generate.py to app folder.
await copy("generate.py", path.join(root), {
parents: true,
cwd: path.join(
templatesDir,
"components",
"vectordbs",
"llamaindexserver",
"llamacloud",
"python",
),
});
}
// Copy README.md
await copy("README-template.md", path.join(root), {
parents: true,
cwd: path.join(templatesDir, "components", "workflows", "python", useCase),
rename: assetRelocator,
});
};
export const installPythonTemplate = async ({
appName,
root,
template,
framework,
vectorDb,
postInstallAction,
modelConfig,
dataSources,
tools,
useLlamaParse,
useCase,
observability,
}: Pick<
InstallTemplateArgs,
| "appName"
| "root"
| "template"
| "framework"
| "vectorDb"
| "postInstallAction"
| "modelConfig"
| "dataSources"
| "tools"
| "useLlamaParse"
| "useCase"
| "observability"
>) => {
console.log("\nInitializing Python project with template:", template, "\n");
let templatePath;
if (template === "reflex") {
templatePath = path.join(templatesDir, "types", "reflex");
} else {
templatePath = path.join(templatesDir, "types", template, framework);
}
await copy("**", root, {
parents: true,
cwd: templatePath,
rename: assetRelocator,
});
if (template === "llamaindexserver") {
await installLlamaIndexServerTemplate({
root,
useCase,
useLlamaParse,
});
} else {
await installLegacyPythonTemplate({
root,
template,
vectorDb,
dataSources,
tools,
useCase,
observability,
});
}
console.log("Adding additional dependencies");
const addOnDependencies = getAdditionalDependencies(
modelConfig,
vectorDb,
dataSources,
tools,
template,
);
await addDependencies(root, addOnDependencies);
@@ -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;
@@ -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.0.3",
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.0.3",
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",
},
],
},
@@ -24,7 +24,8 @@ export type TemplateType =
| "community"
| "llamapack"
| "multiagent"
| "reflex";
| "reflex"
| "llamaindexserver";
export type TemplateFramework = "nextjs" | "express" | "fastapi";
export type TemplateUI = "html" | "shadcn";
export type TemplateVectorDB =
@@ -55,7 +56,8 @@ export type TemplateUseCase =
| "deep_research"
| "form_filling"
| "extractor"
| "contract_review";
| "contract_review"
| "agentic_rag";
// Config for both file and folder
export type FileSourceConfig =
| {
@@ -8,42 +8,104 @@ import { templatesDir } from "./dir";
import { PackageManager } from "./get-pkg-manager";
import { InstallTemplateArgs, ModelProvider, TemplateVectorDB } from "./types";
/**
* Install a LlamaIndex internal template to a given `root` directory.
*/
export const installTSTemplate = async ({
appName,
const installLlamaIndexServerTemplate = async ({
root,
useCase,
vectorDb,
}: Pick<InstallTemplateArgs, "root" | "useCase" | "vectorDb">) => {
if (!useCase) {
console.log(
red(
`There is no use case selected. Please pick a use case to use via --use-case flag.`,
),
);
process.exit(1);
}
if (!vectorDb) {
console.log(
red(
`There is no vector db selected. Please pick a vector db to use via --vector-db flag.`,
),
);
process.exit(1);
}
await copy("workflow.ts", path.join(root, "src", "app"), {
parents: true,
cwd: path.join(
templatesDir,
"components",
"workflows",
"typescript",
useCase,
),
});
// copy workflow UI components to output/components folder
await copy("*", path.join(root, "components"), {
parents: true,
cwd: path.join(templatesDir, "components", "ui", "workflows", useCase),
});
if (vectorDb === "llamacloud") {
await copy("generate.ts", path.join(root, "src"), {
parents: true,
cwd: path.join(
templatesDir,
"components",
"vectordbs",
"llamaindexserver",
"llamacloud",
"typescript",
),
});
await copy("index.ts", path.join(root, "src", "app"), {
parents: true,
cwd: path.join(
templatesDir,
"components",
"vectordbs",
"llamaindexserver",
"llamacloud",
"typescript",
),
rename: () => "data.ts",
});
}
// Copy README.md
await copy("README-template.md", path.join(root), {
parents: true,
cwd: path.join(
templatesDir,
"components",
"workflows",
"typescript",
useCase,
),
rename: assetRelocator,
});
};
const installLegacyTSTemplate = async ({
root,
packageManager,
isOnline,
template,
backend,
framework,
ui,
vectorDb,
postInstallAction,
backend,
observability,
tools,
dataSources,
useLlamaParse,
useCase,
modelConfig,
}: InstallTemplateArgs & { backend: boolean }) => {
console.log(bold(`Using ${packageManager}.`));
/**
* Copy the template files to the target directory.
*/
console.log("\nInitializing project with template:", template, "\n");
const templatePath = path.join(templatesDir, "types", "streaming", framework);
const copySource = ["**"];
await copy(copySource, root, {
parents: true,
cwd: templatePath,
rename: assetRelocator,
});
relativeEngineDestPath,
}: InstallTemplateArgs & {
backend: boolean;
relativeEngineDestPath: string;
}) => {
/**
* If next.js is used, update its configuration if necessary
*/
@@ -98,10 +160,6 @@ export const installTSTemplate = async ({
}
const compPath = path.join(templatesDir, "components");
const relativeEngineDestPath =
framework === "nextjs"
? path.join("app", "api", "chat")
: path.join("src", "controllers");
const enginePath = path.join(root, relativeEngineDestPath, "engine");
// copy llamaindex code for TS templates
@@ -236,6 +294,75 @@ export const installTSTemplate = async ({
await fs.rm(path.join(root, "app", "api"), { recursive: true });
await fs.rm(path.join(root, "config"), { recursive: true, force: true });
}
};
/**
* Install a LlamaIndex internal template to a given `root` directory.
*/
export const installTSTemplate = async ({
appName,
root,
packageManager,
isOnline,
template,
framework,
ui,
vectorDb,
postInstallAction,
backend,
observability,
tools,
dataSources,
useLlamaParse,
useCase,
modelConfig,
}: InstallTemplateArgs & { backend: boolean }) => {
console.log(bold(`Using ${packageManager}.`));
/**
* Copy the template files to the target directory.
*/
console.log("\nInitializing project with template:", template, "\n");
const templatePath = path.join(templatesDir, "types", template, framework);
const copySource = ["**"];
await copy(copySource, root, {
parents: true,
cwd: templatePath,
rename: assetRelocator,
});
const relativeEngineDestPath =
framework === "nextjs"
? path.join("app", "api", "chat")
: path.join("src", "controllers");
if (template === "llamaindexserver") {
await installLlamaIndexServerTemplate({
root,
useCase,
vectorDb,
});
} else {
await installLegacyTSTemplate({
appName,
root,
packageManager,
isOnline,
template,
backend,
framework,
ui,
vectorDb,
observability,
tools,
dataSources,
useLlamaParse,
useCase,
modelConfig,
relativeEngineDestPath,
});
}
const packageJson = await updatePackageJson({
root,
@@ -248,6 +375,7 @@ export const installTSTemplate = async ({
vectorDb,
backend,
modelConfig,
template,
});
if (
@@ -262,27 +390,27 @@ const providerDependencies: {
[key in ModelProvider]?: Record<string, string>;
} = {
openai: {
"@llamaindex/openai": "^0.1.52",
"@llamaindex/openai": "^0.2.0",
},
gemini: {
"@llamaindex/google": "^0.0.7",
"@llamaindex/google": "^0.2.0",
},
ollama: {
"@llamaindex/ollama": "^0.0.40",
"@llamaindex/ollama": "^0.1.0",
},
mistral: {
"@llamaindex/mistral": "^0.0.5",
"@llamaindex/mistral": "^0.2.0",
},
"azure-openai": {
"@llamaindex/openai": "^0.1.52",
"@llamaindex/openai": "^0.2.0",
},
groq: {
"@llamaindex/groq": "^0.0.51",
"@llamaindex/huggingface": "^0.0.36", // groq uses huggingface as default embedding model
"@llamaindex/groq": "^0.0.61",
"@llamaindex/huggingface": "^0.1.0", // groq uses huggingface as default embedding model
},
anthropic: {
"@llamaindex/anthropic": "^0.1.0",
"@llamaindex/huggingface": "^0.0.36", // anthropic uses huggingface as default embedding model
"@llamaindex/anthropic": "^0.3.0",
"@llamaindex/huggingface": "^0.1.0", // anthropic uses huggingface as default embedding model
},
};
@@ -331,6 +459,7 @@ async function updatePackageJson({
vectorDb,
backend,
modelConfig,
template,
}: Pick<
InstallTemplateArgs,
| "root"
@@ -341,6 +470,7 @@ async function updatePackageJson({
| "observability"
| "vectorDb"
| "modelConfig"
| "template"
> & {
relativeEngineDestPath: string;
backend: boolean;
@@ -352,7 +482,7 @@ async function updatePackageJson({
packageJson.name = appName;
packageJson.version = "0.1.0";
if (relativeEngineDestPath) {
if (relativeEngineDestPath && template !== "llamaindexserver") {
// TODO: move script to {root}/scripts for all frameworks
// add generate script if using context engine
packageJson.scripts = {
+42
View File
@@ -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;
}
+83
View File
@@ -0,0 +1,83 @@
{
"name": "create-llama",
"version": "0.5.11",
"description": "Create LlamaIndex-powered apps with one command",
"keywords": [
"rag",
"llamaindex",
"next.js"
],
"repository": {
"type": "git",
"url": "https://github.com/run-llama/create-llama",
"directory": "packages/create-llama"
},
"license": "MIT",
"bin": {
"create-llama": "./dist/index.js"
},
"files": [
"dist",
"README.md",
"LICENSE.md"
],
"scripts": {
"copy": "cp -r ../../README.md ../../LICENSE.md .",
"build": "bash ./scripts/build.sh",
"build:ncc": "pnpm run clean && ncc build ./index.ts -o ./dist/ --minify --no-cache --no-source-map-register",
"postbuild": "pnpm run copy",
"clean": "rimraf --glob ./dist ./templates/**/__pycache__ ./templates/**/node_modules ./templates/**/poetry.lock",
"dev": "ncc build ./index.ts -w -o dist/",
"e2e": "playwright test",
"e2e:python": "playwright test e2e/shared e2e/python",
"e2e:typescript": "playwright test e2e/shared e2e/typescript",
"format": "prettier --ignore-unknown --cache --check .",
"format:write": "prettier --ignore-unknown --write .",
"lint": "eslint . --ignore-pattern dist --ignore-pattern e2e/cache",
"pack-install": "bash ./scripts/pack.sh"
},
"dependencies": {
"@types/async-retry": "1.4.2",
"@types/ci-info": "2.0.0",
"@types/cross-spawn": "6.0.0",
"@types/fs-extra": "11.0.4",
"@types/node": "^20.11.7",
"@types/prompts": "2.4.2",
"@types/tar": "6.1.5",
"@types/validate-npm-package-name": "3.0.0",
"async-retry": "1.3.1",
"async-sema": "3.0.1",
"ci-info": "github:watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540",
"commander": "12.1.0",
"cross-spawn": "7.0.3",
"fast-glob": "3.3.1",
"fs-extra": "11.2.0",
"global-agent": "^3.0.0",
"got": "10.7.0",
"ollama": "^0.5.0",
"ora": "^8.0.1",
"picocolors": "1.0.0",
"prompts": "2.4.2",
"smol-toml": "^1.1.4",
"tar": "6.1.15",
"terminal-link": "^3.0.0",
"update-check": "1.5.4",
"validate-npm-package-name": "3.0.0",
"yaml": "2.4.1"
},
"devDependencies": {
"eslint": "^8.56.0",
"eslint-config-prettier": "^8.10.0",
"prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^3.2.4",
"@playwright/test": "^1.41.1",
"@vercel/ncc": "0.38.1",
"rimraf": "^5.0.5",
"typescript": "^5.3.3",
"wait-port": "^1.1.0"
},
"packageManager": "pnpm@9.0.5",
"engines": {
"node": ">=16.14.0"
}
}
@@ -16,5 +16,6 @@ export const askQuestions = async (
await askProQuestions(args);
return args as unknown as QuestionResults;
}
return await askSimpleQuestions(args);
const results = await askSimpleQuestions(args);
return results;
};
@@ -1,25 +1,12 @@
import prompts from "prompts";
import {
AI_REPORTS,
EXAMPLE_10K_SEC_FILES,
EXAMPLE_FILE,
EXAMPLE_GDPR,
} from "../helpers/datasources";
import { EXAMPLE_10K_SEC_FILES, EXAMPLE_FILE } from "../helpers/datasources";
import { askModelConfig } from "../helpers/providers";
import { getTools } from "../helpers/tools";
import { ModelConfig, TemplateFramework } from "../helpers/types";
import { PureQuestionArgs, QuestionResults } from "./types";
import { askPostInstallAction, questionHandlers } from "./utils";
type AppType =
| "rag"
| "code_artifact"
| "financial_report_agent"
| "form_filling"
| "extractor"
| "contract_review"
| "data_scientist"
| "deep_research";
type AppType = "agentic_rag" | "financial_report" | "deep_research";
type SimpleAnswers = {
appType: AppType;
@@ -35,53 +22,22 @@ export const askSimpleQuestions = async (
{
type: "select",
name: "appType",
message: "What app do you want to build?",
hint: "🤖: Agent, 🔀: Workflow",
message: "What use case do you want to build?",
choices: [
{
title: "🤖 Agentic RAG",
value: "rag",
title: "Agentic RAG",
value: "agentic_rag",
description:
"Chatbot that answers questions based on provided documents.",
},
{
title: "🤖 Data Scientist",
value: "data_scientist",
title: "Financial Report",
value: "financial_report",
description:
"Agent that analyzes data and generates visualizations by using a code interpreter.",
},
{
title: "🤖 Code Artifact Agent",
value: "code_artifact",
description:
"Agent that writes code, runs it in a sandbox, and shows the output in the chat UI.",
},
{
title: "🤖 Information Extractor",
value: "extractor",
description:
"Extracts information from documents and returns it as a structured JSON object.",
},
{
title: "🔀 Financial Report Generator",
value: "financial_report_agent",
description:
"Generates a financial report by analyzing the provided 10-K SEC data. Uses a code interpreter to create charts or to conduct further analysis.",
},
{
title: "🔀 Financial 10k SEC Form Filler",
value: "form_filling",
description:
"Extracts information from 10k SEC data and uses it to fill out a CSV form.",
},
{
title: "🔀 Contract Reviewer",
value: "contract_review",
description:
"Extracts and reviews contracts to ensure compliance with GDPR regulations",
},
{
title: "🔀 Deep Researcher",
title: "Deep Research",
value: "deep_research",
description:
"Researches and analyzes provided documents from multiple perspectives, generating a comprehensive report with citations to support key findings and insights.",
@@ -93,13 +49,10 @@ export const askSimpleQuestions = async (
let language: TemplateFramework = "fastapi";
let llamaCloudKey = args.llamaCloudKey;
let useLlamaCloud = false;
if (
appType !== "extractor" &&
appType !== "contract_review" &&
appType !== "deep_research"
) {
if (appType !== "extractor" && appType !== "contract_review") {
const { language: newLanguage } = await prompts(
{
type: "select",
@@ -170,80 +123,36 @@ const convertAnswers = async (
};
const lookup: Record<
AppType,
Pick<
QuestionResults,
"template" | "tools" | "frontend" | "dataSources" | "useCase"
> & {
Pick<QuestionResults, "template" | "tools" | "dataSources" | "useCase"> & {
modelConfig?: ModelConfig;
}
> = {
rag: {
template: "streaming",
tools: getTools(["weather"]),
frontend: true,
agentic_rag: {
template: "llamaindexserver",
dataSources: [EXAMPLE_FILE],
},
data_scientist: {
template: "streaming",
financial_report: {
template: "llamaindexserver",
dataSources: EXAMPLE_10K_SEC_FILES,
tools: getTools(["interpreter", "document_generator"]),
frontend: true,
dataSources: [],
modelConfig: MODEL_GPT4o,
},
code_artifact: {
template: "streaming",
tools: getTools(["artifact"]),
frontend: true,
dataSources: [],
modelConfig: MODEL_GPT4o,
},
financial_report_agent: {
template: "multiagent",
useCase: "financial_report",
tools: getTools(["document_generator", "interpreter"]),
dataSources: EXAMPLE_10K_SEC_FILES,
frontend: true,
modelConfig: MODEL_GPT4o,
},
form_filling: {
template: "multiagent",
useCase: "form_filling",
tools: getTools(["form_filling"]),
dataSources: EXAMPLE_10K_SEC_FILES,
frontend: true,
modelConfig: MODEL_GPT4o,
},
extractor: {
template: "reflex",
useCase: "extractor",
tools: [],
frontend: false,
dataSources: [EXAMPLE_FILE],
},
contract_review: {
template: "reflex",
useCase: "contract_review",
tools: [],
frontend: false,
dataSources: [EXAMPLE_GDPR],
},
deep_research: {
template: "multiagent",
useCase: "deep_research",
template: "llamaindexserver",
dataSources: EXAMPLE_10K_SEC_FILES,
tools: [],
frontend: true,
dataSources: [AI_REPORTS],
modelConfig: MODEL_GPT4o,
},
};
const results = lookup[answers.appType];
return {
framework: answers.language,
useCase: answers.appType,
ui: "shadcn",
llamaCloudKey: answers.llamaCloudKey,
useLlamaParse: answers.useLlamaCloud,
llamapack: "",
vectorDb: answers.useLlamaCloud ? "llamacloud" : "none",
observability: "none",
...results,
modelConfig:
results.modelConfig ??
@@ -252,6 +161,6 @@ const convertAnswers = async (
askModels: args.askModels ?? false,
framework: answers.language,
})),
frontend: answers.language === "nextjs" ? false : results.frontend,
frontend: true,
};
};
@@ -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

Some files were not shown because too many files have changed in this diff Show More