mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-15 06:52:45 -04:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4589a84643 | |||
| e6b7f52d3e | |||
| b169db617a | |||
| 89a49f4f4f | |||
| 58490715fe | |||
| 4c2283c4e5 | |||
| a059070dec | |||
| 20dfeb4cfa | |||
| aefc3266c1 | |||
| fdf48dd459 | |||
| 66525346a2 | |||
| c9b2ec4a2b | |||
| bf583a7266 | |||
| de194d1c73 | |||
| ecdc289df1 | |||
| 9e198ac40d | |||
| 0a06998690 | |||
| 484a7105a9 | |||
| 8d18ea167b | |||
| a2ca89bfe0 | |||
| edeea40898 | |||
| 2a7080b094 | |||
| b354f2386b | |||
| d766bd03d2 | |||
| 6a69148356 |
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"llamaindex": patch
|
||||
---
|
||||
|
||||
feat: experimental package + json query engine
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"create-llama": patch
|
||||
---
|
||||
|
||||
Add LlamaParse option when selecting a pdf file or a folder
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
"llamaindex": patch
|
||||
"@llamaindex/core-test": patch
|
||||
---
|
||||
|
||||
- Add missing exports:
|
||||
- `IndexStructType`,
|
||||
- `IndexDict`,
|
||||
- `jsonToIndexStruct`,
|
||||
- `IndexList`,
|
||||
- `IndexStruct`
|
||||
- Fix `IndexDict.toJson()` method
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"llamaindex": patch
|
||||
---
|
||||
|
||||
Add streaming to agents
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"llamaindex": minor
|
||||
---
|
||||
|
||||
Use parameter object for retrieve function of Retriever (to align usage with query function of QueryEngine)
|
||||
@@ -11,5 +11,13 @@ module.exports = {
|
||||
"max-params": ["error", 4],
|
||||
"prefer-const": "error",
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["examples/**/*.ts"],
|
||||
rules: {
|
||||
"turbo/no-undeclared-env-vars": "off",
|
||||
},
|
||||
},
|
||||
],
|
||||
ignorePatterns: ["dist/", "lib/"],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
name: Publish
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Publish @llamaindex/env
|
||||
run: npx jsr publish
|
||||
working-directory: packages/env
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish @llamaindex/core
|
||||
run: npx jsr publish --allow-slow-types
|
||||
working-directory: packages/core
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -45,6 +45,7 @@ playwright-report/
|
||||
blob-report/
|
||||
playwright/.cache/
|
||||
.tsbuildinfo
|
||||
packages/create-llama/e2e/cache
|
||||
|
||||
# intellij
|
||||
**/.idea
|
||||
|
||||
@@ -4,3 +4,4 @@ pnpm-lock.yaml
|
||||
lib/
|
||||
dist/
|
||||
.docusaurus/
|
||||
packages/create-llama/e2e/cache/
|
||||
@@ -1,6 +1,6 @@
|
||||
# Transformations
|
||||
|
||||
A transformation is something that takes a list of nodes as an input, and returns a list of nodes. Each component that implements the Transformatio class has both a `transform` definition responsible for transforming the nodes
|
||||
A transformation is something that takes a list of nodes as an input, and returns a list of nodes. Each component that implements the Transformation class has both a `transform` definition responsible for transforming the nodes.
|
||||
|
||||
Currently, the following components are Transformation objects:
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ const response = await queryEngine.query("<user_query>");
|
||||
```ts
|
||||
import { SimilarityPostprocessor } from "llamaindex";
|
||||
|
||||
nodes = await index.asRetriever().retrieve("test query str");
|
||||
nodes = await index.asRetriever().retrieve({ query: "test query str" });
|
||||
|
||||
const processor = new SimilarityPostprocessor({
|
||||
similarityCutoff: 0.7,
|
||||
|
||||
@@ -11,7 +11,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Fetch nodes!
|
||||
const nodesWithScore = await retriever.retrieve("query string");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "query string" });
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// جلب العقد!
|
||||
const nodesWithScore = await retriever.retrieve("سلسلة الاستعلام");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "سلسلة الاستعلام" });
|
||||
```
|
||||
|
||||
## مرجع الواجهة البرمجية (API Reference)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Извличане на върхове!
|
||||
const nodesWithScore = await retriever.retrieve("query string");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "query string" });
|
||||
```
|
||||
|
||||
## API Reference (API справка)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const recuperador = vector_index.asRetriever();
|
||||
recuperador.similarityTopK = 3;
|
||||
|
||||
// Obteniu els nodes!
|
||||
const nodesAmbPuntuació = await recuperador.retrieve("cadena de consulta");
|
||||
const nodesAmbPuntuació = await recuperador.retrieve({ query: "cadena de consulta" });
|
||||
```
|
||||
|
||||
## Referència de l'API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Získání uzlů!
|
||||
const nodesWithScore = await retriever.retrieve("dotazovací řetězec");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "dotazovací řetězec" });
|
||||
```
|
||||
|
||||
## API Reference (Odkazy na rozhraní)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Hent noder!
|
||||
const nodesWithScore = await retriever.retrieve("forespørgselsstreng");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "forespørgselsstreng" });
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Knoten abrufen!
|
||||
const nodesWithScore = await retriever.retrieve("Abfragezeichenfolge");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "Abfragezeichenfolge" });
|
||||
```
|
||||
|
||||
## API-Referenz
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Ανάκτηση κόμβων!
|
||||
const nodesWithScore = await retriever.retrieve("συμβολοσειρά ερωτήματος");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "συμβολοσειρά ερωτήματος" });
|
||||
```
|
||||
|
||||
## Αναφορά API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const recuperador = vector_index.asRetriever();
|
||||
recuperador.similarityTopK = 3;
|
||||
|
||||
// ¡Obtener nodos!
|
||||
const nodosConPuntuación = await recuperador.retrieve("cadena de consulta");
|
||||
const nodosConPuntuación = await recuperador.retrieve({ query: "cadena de consulta" });
|
||||
```
|
||||
|
||||
## Referencia de la API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Too sõlmed!
|
||||
const nodesWithScore = await retriever.retrieve("päringu string");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "päringu string" });
|
||||
```
|
||||
|
||||
## API viide
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// بازیابی گره ها!
|
||||
const nodesWithScore = await retriever.retrieve("رشته پرس و جو");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "رشته پرس و جو" });
|
||||
```
|
||||
|
||||
## مرجع API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Hae solmut!
|
||||
const nodesWithScore = await retriever.retrieve("kyselymerkkijono");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "kyselymerkkijono" });
|
||||
```
|
||||
|
||||
## API-viite
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Récupérer les nœuds !
|
||||
const nodesWithScore = await retriever.retrieve("chaîne de requête");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "chaîne de requête" });
|
||||
```
|
||||
|
||||
## Référence de l'API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// אחזור צמתים!
|
||||
const nodesWithScore = await retriever.retrieve("מחרוזת שאילתה");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "מחרוזת שאילתה" });
|
||||
```
|
||||
|
||||
## מדריך לממשק API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// नोड्स प्राप्त करें!
|
||||
const nodesWithScore = await retriever.retrieve("क्वेरी स्ट्रिंग");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "क्वेरी स्ट्रिंग" });
|
||||
```
|
||||
|
||||
## एपीआई संदर्भ (API Reference)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const dohvatnik = vector_index.asRetriever();
|
||||
dohvatnik.similarityTopK = 3;
|
||||
|
||||
// Dohvati čvorove!
|
||||
const čvoroviSaRezultatom = await dohvatnik.retrieve("upitni niz");
|
||||
const čvoroviSaRezultatom = await dohvatnik.retrieve({ query: "upitni niz" });
|
||||
```
|
||||
|
||||
## API Referenca
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Node-ok lekérése!
|
||||
const nodesWithScore = await retriever.retrieve("lekérdezési karakterlánc");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "lekérdezési karakterlánc" });
|
||||
```
|
||||
|
||||
## API Referencia
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Mengambil node!
|
||||
const nodesWithScore = await retriever.retrieve("string query");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "string query" });
|
||||
```
|
||||
|
||||
## Referensi API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Recupera i nodi!
|
||||
const nodesWithScore = await retriever.retrieve("stringa di query");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "stringa di query" });
|
||||
```
|
||||
|
||||
## Riferimento API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// ノードを取得します!
|
||||
const nodesWithScore = await retriever.retrieve("クエリ文字列");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "クエリ文字列" });
|
||||
```
|
||||
|
||||
## API リファレンス
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// 노드를 가져옵니다!
|
||||
const nodesWithScore = await retriever.retrieve("쿼리 문자열");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "쿼리 문자열" });
|
||||
```
|
||||
|
||||
## API 참조
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const gavėjas = vector_index.asRetriever();
|
||||
gavėjas.similarityTopK = 3;
|
||||
|
||||
// Išgaunami mazgai!
|
||||
const mazgaiSuRezultatu = await gavėjas.retrieve("užklausos eilutė");
|
||||
const mazgaiSuRezultatu = await gavėjas.retrieve({ query: "užklausos eilutė" });
|
||||
```
|
||||
|
||||
## API nuorodos (API Reference)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Haal knooppunten op!
|
||||
const nodesWithScore = await retriever.retrieve("zoekopdracht");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "zoekopdracht" });
|
||||
```
|
||||
|
||||
## API Referentie
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Hent noder!
|
||||
const nodesWithScore = await retriever.retrieve("spørringsstreng");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "spørringsstreng" });
|
||||
```
|
||||
|
||||
## API-referanse
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Pobierz węzły!
|
||||
const nodesWithScore = await retriever.retrieve("ciąg zapytania");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "ciąg zapytania" });
|
||||
```
|
||||
|
||||
## Dokumentacja interfejsu API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const recuperador = vector_index.asRetriever();
|
||||
recuperador.similarityTopK = 3;
|
||||
|
||||
// Buscar nós!
|
||||
const nósComPontuação = await recuperador.retrieve("string de consulta");
|
||||
const nósComPontuação = await recuperador.retrieve({ query: "string de consulta" });
|
||||
```
|
||||
|
||||
## Referência da API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const recuperator = vector_index.asRetriever();
|
||||
recuperator.similarityTopK = 3;
|
||||
|
||||
// Preia nodurile!
|
||||
const noduriCuScor = await recuperator.retrieve("șir de interogare");
|
||||
const noduriCuScor = await recuperator.retrieve({ query: "șir de interogare" });
|
||||
```
|
||||
|
||||
## Referință API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Получение узлов!
|
||||
const nodesWithScore = await retriever.retrieve("строка запроса");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "строка запроса" });
|
||||
```
|
||||
|
||||
## Справочник по API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Dohvati čvorove!
|
||||
const nodesWithScore = await retriever.retrieve("upitni niz");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "upitni niz" });
|
||||
```
|
||||
|
||||
## API Referenca
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const pridobitelj = vector_index.asRetriever();
|
||||
pridobitelj.similarityTopK = 3;
|
||||
|
||||
// Pridobivanje vozlišč!
|
||||
const vozliščaZRezultatom = await pridobitelj.retrieve("poizvedbeni niz");
|
||||
const vozliščaZRezultatom = await pridobitelj.retrieve({ query: "poizvedbeni niz" });
|
||||
```
|
||||
|
||||
## API Sklic
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Získajte uzly!
|
||||
const nodesWithScore = await retriever.retrieve("reťazec dotazu");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "reťazec dotazu" });
|
||||
```
|
||||
|
||||
## API Referencia
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Hämta noder!
|
||||
const nodesWithScore = await retriever.retrieve("frågesträng");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "frågesträng" });
|
||||
```
|
||||
|
||||
## API-referens
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// เรียกคืนโหนด!
|
||||
const nodesWithScore = await retriever.retrieve("query string");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "query string" });
|
||||
```
|
||||
|
||||
## API Reference (การอ้างอิง API)
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Düğümleri getir!
|
||||
const nodesWithScore = await retriever.retrieve("sorgu dizesi");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "sorgu dizesi" });
|
||||
```
|
||||
|
||||
## API Referansı
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Отримати вузли!
|
||||
const nodesWithScore = await retriever.retrieve("рядок запиту");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "рядок запиту" });
|
||||
```
|
||||
|
||||
## Довідник API
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// Lấy các node!
|
||||
const nodesWithScore = await retriever.retrieve("chuỗi truy vấn");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "chuỗi truy vấn" });
|
||||
```
|
||||
|
||||
## Tài liệu tham khảo API
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// 获取节点!
|
||||
const nodesWithScore = await retriever.retrieve("查询字符串");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "查询字符串" });
|
||||
```
|
||||
|
||||
## API 参考
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const retriever = vector_index.asRetriever();
|
||||
retriever.similarityTopK = 3;
|
||||
|
||||
// 提取節點!
|
||||
const nodesWithScore = await retriever.retrieve("查詢字串");
|
||||
const nodesWithScore = await retriever.retrieve({ query: "查詢字串" });
|
||||
```
|
||||
|
||||
## API 參考
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { FunctionTool, OpenAIAgent } from "llamaindex";
|
||||
|
||||
// Define a function to sum two numbers
|
||||
function sumNumbers({ a, b }: { a: number; b: number }): number {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// Define a function to divide two numbers
|
||||
function divideNumbers({ a, b }: { a: number; b: number }): number {
|
||||
return a / b;
|
||||
}
|
||||
|
||||
// Define the parameters of the sum function as a JSON schema
|
||||
const sumJSON = {
|
||||
type: "object",
|
||||
properties: {
|
||||
a: {
|
||||
type: "number",
|
||||
description: "The first number",
|
||||
},
|
||||
b: {
|
||||
type: "number",
|
||||
description: "The second number",
|
||||
},
|
||||
},
|
||||
required: ["a", "b"],
|
||||
};
|
||||
|
||||
const divideJSON = {
|
||||
type: "object",
|
||||
properties: {
|
||||
a: {
|
||||
type: "number",
|
||||
description: "The dividend",
|
||||
},
|
||||
b: {
|
||||
type: "number",
|
||||
description: "The divisor",
|
||||
},
|
||||
},
|
||||
required: ["a", "b"],
|
||||
};
|
||||
|
||||
async function main() {
|
||||
// Create a function tool from the sum function
|
||||
const functionTool = new FunctionTool(sumNumbers, {
|
||||
name: "sumNumbers",
|
||||
description: "Use this function to sum two numbers",
|
||||
parameters: sumJSON,
|
||||
});
|
||||
|
||||
// Create a function tool from the divide function
|
||||
const functionTool2 = new FunctionTool(divideNumbers, {
|
||||
name: "divideNumbers",
|
||||
description: "Use this function to divide two numbers",
|
||||
parameters: divideJSON,
|
||||
});
|
||||
|
||||
// Create an OpenAIAgent with the function tools
|
||||
const agent = new OpenAIAgent({
|
||||
tools: [functionTool, functionTool2],
|
||||
verbose: false,
|
||||
});
|
||||
|
||||
const stream = await agent.chat({
|
||||
message: "Divide 16 by 2 then add 20",
|
||||
stream: true,
|
||||
});
|
||||
|
||||
for await (const chunk of stream.response) {
|
||||
process.stdout.write(chunk.response);
|
||||
}
|
||||
}
|
||||
|
||||
main().then(() => {
|
||||
console.log("\nDone");
|
||||
});
|
||||
@@ -27,9 +27,9 @@ async function main() {
|
||||
// retrieve documents using the index
|
||||
const index = await createIndex();
|
||||
const retriever = index.asRetriever({ similarityTopK: 3 });
|
||||
const results = await retriever.retrieve(
|
||||
"what are Vincent van Gogh's famous paintings",
|
||||
);
|
||||
const results = await retriever.retrieve({
|
||||
query: "what are Vincent van Gogh's famous paintings",
|
||||
});
|
||||
for (const result of results) {
|
||||
const node = result.node;
|
||||
if (!node) {
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@
|
||||
"type-check": "tsc -b --diagnostics",
|
||||
"release": "pnpm run build:release && changeset publish",
|
||||
"new-llamaindex": "pnpm run build:release && changeset version --ignore create-llama",
|
||||
"new-create-llama": "pnpm run build:release && changeset version --ignore llamaindex",
|
||||
"new-snapshots": "pnpm run build:release && changeset version --snapshot"
|
||||
"new-create-llama": "pnpm run build:release && changeset version --ignore llamaindex --ignore @llamaindex/core-test",
|
||||
"new-experimental": "pnpm run build:release && changeset version --ignore create-llama"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.27.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@llamaindex/core",
|
||||
"version": "0.1.20",
|
||||
"version": "0.1.21",
|
||||
"exports": "./src/index.ts",
|
||||
"imports": {
|
||||
"@llamaindex/env": "jsr:@llamaindex/env@0.0.5"
|
||||
|
||||
@@ -92,9 +92,9 @@
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"build": "rm -rf ./dist && pnpm run build:esm && pnpm run build:cjs && pnpm run build:type",
|
||||
"build:esm": "swc src -d dist --strip-leading-paths --config-file .swcrc",
|
||||
"build:cjs": "swc src -d dist/cjs --strip-leading-paths --config-file .cjs.swcrc",
|
||||
"build:type": "pnpm run -w type-check",
|
||||
"build:esm": "swc src -d dist --strip-leading-paths --config-file ../../.swcrc",
|
||||
"build:cjs": "swc src -d dist/cjs --strip-leading-paths --config-file ../../.cjs.swcrc",
|
||||
"build:type": "tsc -p tsconfig.json",
|
||||
"copy": "cp -r ../../README.md ../../LICENSE .",
|
||||
"postbuild": "pnpm run copy && node -e \"require('fs').writeFileSync('./dist/cjs/package.json', JSON.stringify({ type: 'commonjs' }))\"",
|
||||
"circular-check": "madge -c ./src/index.ts",
|
||||
|
||||
@@ -2,14 +2,16 @@ import type { Event } from "./callbacks/CallbackManager.js";
|
||||
import type { NodeWithScore } from "./Node.js";
|
||||
import type { ServiceContext } from "./ServiceContext.js";
|
||||
|
||||
export type RetrieveParams = {
|
||||
query: string;
|
||||
parentEvent?: Event;
|
||||
preFilters?: unknown;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrievers retrieve the nodes that most closely match our query in similarity.
|
||||
*/
|
||||
export interface BaseRetriever {
|
||||
retrieve(
|
||||
query: string,
|
||||
parentEvent?: Event,
|
||||
preFilters?: unknown,
|
||||
): Promise<NodeWithScore[]>;
|
||||
retrieve(params: RetrieveParams): Promise<NodeWithScore[]>;
|
||||
getServiceContext(): ServiceContext;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Assuming that the necessary interfaces and classes (like BaseTool, OpenAI, ChatMessage, CallbackManager, etc.) are defined elsewhere
|
||||
|
||||
import { randomUUID } from "@llamaindex/env";
|
||||
import { Response } from "../../Response.js";
|
||||
import type { CallbackManager } from "../../callbacks/CallbackManager.js";
|
||||
import {
|
||||
AgentChatResponse,
|
||||
ChatResponseMode,
|
||||
StreamingAgentChatResponse,
|
||||
} from "../../engines/chat/types.js";
|
||||
import type {
|
||||
ChatMessage,
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
ChatResponseChunk,
|
||||
} from "../../llm/index.js";
|
||||
import { OpenAI } from "../../llm/index.js";
|
||||
import { streamConverter, streamReducer } from "../../llm/utils.js";
|
||||
import { ChatMemoryBuffer } from "../../memory/ChatMemoryBuffer.js";
|
||||
import type { ObjectRetriever } from "../../objects/base.js";
|
||||
import type { ToolOutput } from "../../tools/types.js";
|
||||
@@ -192,13 +193,40 @@ export class OpenAIAgentWorker implements AgentWorker {
|
||||
private _processMessage(
|
||||
task: Task,
|
||||
chatResponse: ChatResponse,
|
||||
): AgentChatResponse | AsyncIterable<ChatResponseChunk> {
|
||||
): AgentChatResponse {
|
||||
const aiMessage = chatResponse.message;
|
||||
task.extraState.newMemory.put(aiMessage);
|
||||
|
||||
return new AgentChatResponse(aiMessage.content, task.extraState.sources);
|
||||
}
|
||||
|
||||
private async _getStreamAiResponse(
|
||||
task: Task,
|
||||
llmChatKwargs: any,
|
||||
): Promise<StreamingAgentChatResponse> {
|
||||
const stream = await this.llm.chat({
|
||||
stream: true,
|
||||
...llmChatKwargs,
|
||||
});
|
||||
|
||||
const iterator = streamConverter(
|
||||
streamReducer({
|
||||
stream,
|
||||
initialValue: "",
|
||||
reducer: (accumulator, part) => (accumulator += part.delta),
|
||||
finished: (accumulator) => {
|
||||
task.extraState.newMemory.put({
|
||||
content: accumulator,
|
||||
role: "assistant",
|
||||
});
|
||||
},
|
||||
}),
|
||||
(r: ChatResponseChunk) => new Response(r.delta),
|
||||
);
|
||||
|
||||
return new StreamingAgentChatResponse(iterator, task.extraState.sources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get agent response.
|
||||
* @param task: task
|
||||
@@ -210,7 +238,7 @@ export class OpenAIAgentWorker implements AgentWorker {
|
||||
task: Task,
|
||||
mode: ChatResponseMode,
|
||||
llmChatKwargs: any,
|
||||
): Promise<AgentChatResponse> {
|
||||
): Promise<AgentChatResponse | StreamingAgentChatResponse> {
|
||||
if (mode === ChatResponseMode.WAIT) {
|
||||
const chatResponse = (await this.llm.chat({
|
||||
stream: false,
|
||||
@@ -218,9 +246,11 @@ export class OpenAIAgentWorker implements AgentWorker {
|
||||
})) as unknown as ChatResponse;
|
||||
|
||||
return this._processMessage(task, chatResponse) as AgentChatResponse;
|
||||
} else {
|
||||
throw new Error("Not implemented");
|
||||
} else if (mode === ChatResponseMode.STREAM) {
|
||||
return this._getStreamAiResponse(task, llmChatKwargs);
|
||||
}
|
||||
|
||||
throw new Error("Invalid mode");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { ChatEngineAgentParams } from "../../engines/chat/index.js";
|
||||
import {
|
||||
AgentChatResponse,
|
||||
ChatResponseMode,
|
||||
StreamingAgentChatResponse,
|
||||
} from "../../engines/chat/index.js";
|
||||
import type { ChatMessage, LLM } from "../../llm/index.js";
|
||||
import { ChatMemoryBuffer } from "../../memory/ChatMemoryBuffer.js";
|
||||
@@ -231,23 +232,26 @@ export class AgentRunner extends BaseAgentRunner {
|
||||
taskId: string,
|
||||
stepOutput: TaskStepOutput,
|
||||
kwargs?: any,
|
||||
): Promise<AgentChatResponse> {
|
||||
): Promise<AgentChatResponse | StreamingAgentChatResponse> {
|
||||
if (!stepOutput) {
|
||||
stepOutput =
|
||||
this.getCompletedSteps(taskId)[
|
||||
this.getCompletedSteps(taskId).length - 1
|
||||
];
|
||||
}
|
||||
|
||||
if (!stepOutput.isLast) {
|
||||
throw new Error(
|
||||
"finalizeResponse can only be called on the last step output",
|
||||
);
|
||||
}
|
||||
|
||||
if (!(stepOutput.output instanceof AgentChatResponse)) {
|
||||
throw new Error(
|
||||
`When \`isLast\` is True, cur_step_output.output must be AGENT_CHAT_RESPONSE_TYPE: ${stepOutput.output}`,
|
||||
);
|
||||
if (!(stepOutput.output instanceof StreamingAgentChatResponse)) {
|
||||
if (!(stepOutput.output instanceof AgentChatResponse)) {
|
||||
throw new Error(
|
||||
`When \`isLast\` is True, cur_step_output.output must be AGENT_CHAT_RESPONSE_TYPE: ${stepOutput.output}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.agentWorker.finalizeTask(this.getTask(taskId), kwargs);
|
||||
@@ -262,20 +266,32 @@ export class AgentRunner extends BaseAgentRunner {
|
||||
protected async _chat({
|
||||
message,
|
||||
toolChoice,
|
||||
}: ChatEngineAgentParams & { mode: ChatResponseMode }) {
|
||||
stream,
|
||||
}: ChatEngineAgentParams): Promise<AgentChatResponse>;
|
||||
protected async _chat({
|
||||
message,
|
||||
toolChoice,
|
||||
stream,
|
||||
}: ChatEngineAgentParams & {
|
||||
stream: true;
|
||||
}): Promise<StreamingAgentChatResponse>;
|
||||
protected async _chat({
|
||||
message,
|
||||
toolChoice,
|
||||
stream,
|
||||
}: ChatEngineAgentParams): Promise<
|
||||
AgentChatResponse | StreamingAgentChatResponse
|
||||
> {
|
||||
const task = this.createTask(message as string);
|
||||
|
||||
let resultOutput;
|
||||
|
||||
const mode = stream ? ChatResponseMode.STREAM : ChatResponseMode.WAIT;
|
||||
|
||||
while (true) {
|
||||
const curStepOutput = await this._runStep(
|
||||
task.taskId,
|
||||
undefined,
|
||||
ChatResponseMode.WAIT,
|
||||
{
|
||||
toolChoice,
|
||||
},
|
||||
);
|
||||
const curStepOutput = await this._runStep(task.taskId, undefined, mode, {
|
||||
toolChoice,
|
||||
});
|
||||
|
||||
if (curStepOutput.isLast) {
|
||||
resultOutput = curStepOutput;
|
||||
@@ -299,7 +315,26 @@ export class AgentRunner extends BaseAgentRunner {
|
||||
message,
|
||||
chatHistory,
|
||||
toolChoice,
|
||||
}: ChatEngineAgentParams): Promise<AgentChatResponse> {
|
||||
stream,
|
||||
}: ChatEngineAgentParams & {
|
||||
stream?: false;
|
||||
}): Promise<AgentChatResponse>;
|
||||
public async chat({
|
||||
message,
|
||||
chatHistory,
|
||||
toolChoice,
|
||||
stream,
|
||||
}: ChatEngineAgentParams & {
|
||||
stream: true;
|
||||
}): Promise<StreamingAgentChatResponse>;
|
||||
public async chat({
|
||||
message,
|
||||
chatHistory,
|
||||
toolChoice,
|
||||
stream,
|
||||
}: ChatEngineAgentParams): Promise<
|
||||
AgentChatResponse | StreamingAgentChatResponse
|
||||
> {
|
||||
if (!toolChoice) {
|
||||
toolChoice = this.defaultToolChoice;
|
||||
}
|
||||
@@ -308,7 +343,7 @@ export class AgentRunner extends BaseAgentRunner {
|
||||
message,
|
||||
chatHistory,
|
||||
toolChoice,
|
||||
mode: ChatResponseMode.WAIT,
|
||||
stream,
|
||||
});
|
||||
|
||||
return chatResponse;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import type { AgentChatResponse } from "../../engines/chat/index.js";
|
||||
import type {
|
||||
AgentChatResponse,
|
||||
StreamingAgentChatResponse,
|
||||
} from "../../engines/chat/index.js";
|
||||
import type { Task, TaskStep, TaskStepOutput } from "../types.js";
|
||||
import { BaseAgent } from "../types.js";
|
||||
|
||||
@@ -57,7 +60,7 @@ export abstract class BaseAgentRunner extends BaseAgent {
|
||||
taskId: string,
|
||||
stepOutput: TaskStepOutput,
|
||||
kwargs?: any,
|
||||
): Promise<AgentChatResponse>;
|
||||
): Promise<AgentChatResponse | StreamingAgentChatResponse>;
|
||||
|
||||
abstract undoStep(taskId: string): void;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import type {
|
||||
AgentChatResponse,
|
||||
ChatEngineAgentParams,
|
||||
StreamingAgentChatResponse,
|
||||
} from "../engines/chat/index.js";
|
||||
|
||||
import type { QueryEngineParamsNonStreaming } from "../types.js";
|
||||
|
||||
export interface AgentWorker {
|
||||
@@ -12,11 +14,15 @@ export interface AgentWorker {
|
||||
}
|
||||
|
||||
interface BaseChatEngine {
|
||||
chat(params: ChatEngineAgentParams): Promise<AgentChatResponse>;
|
||||
chat(
|
||||
params: ChatEngineAgentParams,
|
||||
): Promise<AgentChatResponse | StreamingAgentChatResponse>;
|
||||
}
|
||||
|
||||
interface BaseQueryEngine {
|
||||
query(params: QueryEngineParamsNonStreaming): Promise<AgentChatResponse>;
|
||||
query(
|
||||
params: QueryEngineParamsNonStreaming,
|
||||
): Promise<AgentChatResponse | StreamingAgentChatResponse>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +37,10 @@ export abstract class BaseAgent implements BaseChatEngine, BaseQueryEngine {
|
||||
return [];
|
||||
}
|
||||
|
||||
abstract chat(params: ChatEngineAgentParams): Promise<AgentChatResponse>;
|
||||
abstract chat(
|
||||
params: ChatEngineAgentParams,
|
||||
): Promise<AgentChatResponse | StreamingAgentChatResponse>;
|
||||
|
||||
abstract reset(): void;
|
||||
|
||||
/**
|
||||
@@ -41,7 +50,7 @@ export abstract class BaseAgent implements BaseChatEngine, BaseQueryEngine {
|
||||
*/
|
||||
async query(
|
||||
params: QueryEngineParamsNonStreaming,
|
||||
): Promise<AgentChatResponse> {
|
||||
): Promise<AgentChatResponse | StreamingAgentChatResponse> {
|
||||
// Handle non-streaming query
|
||||
const agentResponse = await this.chat({
|
||||
message: params.query,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { RetrieverQueryEngine } from "../engines/query/RetrieverQueryEngine.js";
|
||||
import type { BaseNodePostprocessor } from "../postprocessors/types.js";
|
||||
import type { BaseSynthesizer } from "../synthesizers/types.js";
|
||||
import type { BaseQueryEngine } from "../types.js";
|
||||
import type { RetrieveParams } from "./LlamaCloudRetriever.js";
|
||||
import type { CloudRetrieveParams } from "./LlamaCloudRetriever.js";
|
||||
import { LlamaCloudRetriever } from "./LlamaCloudRetriever.js";
|
||||
import type { CloudConstructorParams } from "./types.js";
|
||||
|
||||
@@ -14,7 +14,7 @@ export class LlamaCloudIndex {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
asRetriever(params: RetrieveParams = {}): BaseRetriever {
|
||||
asRetriever(params: CloudRetrieveParams = {}): BaseRetriever {
|
||||
return new LlamaCloudRetriever({ ...this.params, ...params });
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export class LlamaCloudIndex {
|
||||
responseSynthesizer?: BaseSynthesizer;
|
||||
preFilters?: unknown;
|
||||
nodePostprocessors?: BaseNodePostprocessor[];
|
||||
} & RetrieveParams,
|
||||
} & CloudRetrieveParams,
|
||||
): BaseQueryEngine {
|
||||
const retriever = new LlamaCloudRetriever({
|
||||
...this.params,
|
||||
|
||||
@@ -2,15 +2,14 @@ import type { PlatformApi, PlatformApiClient } from "@llamaindex/cloud";
|
||||
import { globalsHelper } from "../GlobalsHelper.js";
|
||||
import type { NodeWithScore } from "../Node.js";
|
||||
import { ObjectType, jsonToNode } from "../Node.js";
|
||||
import type { BaseRetriever } from "../Retriever.js";
|
||||
import type { BaseRetriever, RetrieveParams } from "../Retriever.js";
|
||||
import type { ServiceContext } from "../ServiceContext.js";
|
||||
import { serviceContextFromDefaults } from "../ServiceContext.js";
|
||||
import type { Event } from "../callbacks/CallbackManager.js";
|
||||
import type { ClientParams, CloudConstructorParams } from "./types.js";
|
||||
import { DEFAULT_PROJECT_NAME } from "./types.js";
|
||||
import { getClient } from "./utils.js";
|
||||
|
||||
export type RetrieveParams = Omit<
|
||||
export type CloudRetrieveParams = Omit<
|
||||
PlatformApi.RetrievalParams,
|
||||
"query" | "searchFilters" | "pipelineId" | "className"
|
||||
> & { similarityTopK?: number };
|
||||
@@ -18,7 +17,7 @@ export type RetrieveParams = Omit<
|
||||
export class LlamaCloudRetriever implements BaseRetriever {
|
||||
client?: PlatformApiClient;
|
||||
clientParams: ClientParams;
|
||||
retrieveParams: RetrieveParams;
|
||||
retrieveParams: CloudRetrieveParams;
|
||||
projectName: string = DEFAULT_PROJECT_NAME;
|
||||
pipelineName: string;
|
||||
serviceContext: ServiceContext;
|
||||
@@ -35,7 +34,7 @@ export class LlamaCloudRetriever implements BaseRetriever {
|
||||
});
|
||||
}
|
||||
|
||||
constructor(params: CloudConstructorParams & RetrieveParams) {
|
||||
constructor(params: CloudConstructorParams & CloudRetrieveParams) {
|
||||
this.clientParams = { apiKey: params.apiKey, baseUrl: params.baseUrl };
|
||||
if (params.similarityTopK) {
|
||||
params.denseSimilarityTopK = params.similarityTopK;
|
||||
@@ -55,11 +54,11 @@ export class LlamaCloudRetriever implements BaseRetriever {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
async retrieve(
|
||||
query: string,
|
||||
parentEvent?: Event | undefined,
|
||||
preFilters?: unknown,
|
||||
): Promise<NodeWithScore[]> {
|
||||
async retrieve({
|
||||
query,
|
||||
parentEvent,
|
||||
preFilters,
|
||||
}: RetrieveParams): Promise<NodeWithScore[]> {
|
||||
const pipelines = await (
|
||||
await this.getClient()
|
||||
).pipeline.searchPipelines({
|
||||
|
||||
@@ -64,10 +64,10 @@ export class DefaultContextGenerator
|
||||
tags: ["final"],
|
||||
};
|
||||
}
|
||||
const sourceNodesWithScore = await this.retriever.retrieve(
|
||||
message,
|
||||
const sourceNodesWithScore = await this.retriever.retrieve({
|
||||
query: message,
|
||||
parentEvent,
|
||||
);
|
||||
});
|
||||
|
||||
const nodes = await this.applyNodePostprocessors(
|
||||
sourceNodesWithScore,
|
||||
|
||||
@@ -27,6 +27,7 @@ export interface ChatEngineParamsNonStreaming extends ChatEngineParamsBase {
|
||||
|
||||
export interface ChatEngineAgentParams extends ChatEngineParamsBase {
|
||||
toolChoice?: string | Record<string, any>;
|
||||
stream?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,3 +87,20 @@ export class AgentChatResponse {
|
||||
return this.response ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
export class StreamingAgentChatResponse {
|
||||
response: AsyncIterable<Response>;
|
||||
|
||||
sources: ToolOutput[];
|
||||
sourceNodes?: BaseNode[];
|
||||
|
||||
constructor(
|
||||
response: AsyncIterable<Response>,
|
||||
sources?: ToolOutput[],
|
||||
sourceNodes?: BaseNode[],
|
||||
) {
|
||||
this.response = response;
|
||||
this.sources = sources ?? [];
|
||||
this.sourceNodes = sourceNodes ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,11 +63,11 @@ export class RetrieverQueryEngine
|
||||
}
|
||||
|
||||
private async retrieve(query: string, parentEvent: Event) {
|
||||
const nodes = await this.retriever.retrieve(
|
||||
const nodes = await this.retriever.retrieve({
|
||||
query,
|
||||
parentEvent,
|
||||
this.preFilters,
|
||||
);
|
||||
preFilters: this.preFilters,
|
||||
});
|
||||
|
||||
return await this.applyNodePostprocessors(nodes, query);
|
||||
}
|
||||
|
||||
@@ -30,3 +30,4 @@ export * from "./selectors/index.js";
|
||||
export * from "./storage/index.js";
|
||||
export * from "./synthesizers/index.js";
|
||||
export * from "./tools/index.js";
|
||||
export * from "./types.js";
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export * from "./BaseIndex.js";
|
||||
export * from "./IndexStruct.js";
|
||||
export * from "./json-to-index-struct.js";
|
||||
export * from "./keyword/index.js";
|
||||
export * from "./summary/index.js";
|
||||
export * from "./vectorStore/index.js";
|
||||
|
||||
@@ -24,9 +24,15 @@ export class IndexDict extends IndexStruct {
|
||||
}
|
||||
|
||||
toJson(): Record<string, unknown> {
|
||||
const nodesDict: Record<string, unknown> = {};
|
||||
|
||||
for (const [key, node] of Object.entries(this.nodesDict)) {
|
||||
nodesDict[key] = node.toJSON();
|
||||
}
|
||||
|
||||
return {
|
||||
...super.toJson(),
|
||||
nodesDict: this.nodesDict,
|
||||
nodesDict,
|
||||
type: this.type,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
defaultKeywordExtractPrompt,
|
||||
defaultQueryKeywordExtractPrompt,
|
||||
} from "../../Prompt.js";
|
||||
import type { BaseRetriever } from "../../Retriever.js";
|
||||
import type { BaseRetriever, RetrieveParams } from "../../Retriever.js";
|
||||
import type { ServiceContext } from "../../ServiceContext.js";
|
||||
import { serviceContextFromDefaults } from "../../ServiceContext.js";
|
||||
import { RetrieverQueryEngine } from "../../engines/query/index.js";
|
||||
@@ -79,7 +79,7 @@ abstract class BaseKeywordTableRetriever implements BaseRetriever {
|
||||
|
||||
abstract getKeywords(query: string): Promise<string[]>;
|
||||
|
||||
async retrieve(query: string): Promise<NodeWithScore[]> {
|
||||
async retrieve({ query }: RetrieveParams): Promise<NodeWithScore[]> {
|
||||
const keywords = await this.getKeywords(query);
|
||||
const chunkIndicesCount: { [key: string]: number } = {};
|
||||
const filteredKeywords = keywords.filter((keyword) =>
|
||||
|
||||
@@ -3,10 +3,9 @@ import { globalsHelper } from "../../GlobalsHelper.js";
|
||||
import type { BaseNode, Document, NodeWithScore } from "../../Node.js";
|
||||
import type { ChoiceSelectPrompt } from "../../Prompt.js";
|
||||
import { defaultChoiceSelectPrompt } from "../../Prompt.js";
|
||||
import type { BaseRetriever } from "../../Retriever.js";
|
||||
import type { BaseRetriever, RetrieveParams } from "../../Retriever.js";
|
||||
import type { ServiceContext } from "../../ServiceContext.js";
|
||||
import { serviceContextFromDefaults } from "../../ServiceContext.js";
|
||||
import type { Event } from "../../callbacks/CallbackManager.js";
|
||||
import { RetrieverQueryEngine } from "../../engines/query/index.js";
|
||||
import type { BaseNodePostprocessor } from "../../postprocessors/index.js";
|
||||
import type {
|
||||
@@ -281,7 +280,10 @@ export class SummaryIndexRetriever implements BaseRetriever {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
async retrieve(query: string, parentEvent?: Event): Promise<NodeWithScore[]> {
|
||||
async retrieve({
|
||||
query,
|
||||
parentEvent,
|
||||
}: RetrieveParams): Promise<NodeWithScore[]> {
|
||||
const nodeIds = this.index.indexStruct.nodes;
|
||||
const nodes = await this.index.docStore.getNodes(nodeIds);
|
||||
const result = nodes.map((node) => ({
|
||||
@@ -337,7 +339,10 @@ export class SummaryIndexLLMRetriever implements BaseRetriever {
|
||||
this.serviceContext = serviceContext || index.serviceContext;
|
||||
}
|
||||
|
||||
async retrieve(query: string, parentEvent?: Event): Promise<NodeWithScore[]> {
|
||||
async retrieve({
|
||||
query,
|
||||
parentEvent,
|
||||
}: RetrieveParams): Promise<NodeWithScore[]> {
|
||||
const nodeIds = this.index.indexStruct.nodes;
|
||||
const results: NodeWithScore[] = [];
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
ObjectType,
|
||||
splitNodesByType,
|
||||
} from "../../Node.js";
|
||||
import type { BaseRetriever } from "../../Retriever.js";
|
||||
import type { BaseRetriever, RetrieveParams } from "../../Retriever.js";
|
||||
import type { ServiceContext } from "../../ServiceContext.js";
|
||||
import { serviceContextFromDefaults } from "../../ServiceContext.js";
|
||||
import type { Event } from "../../callbacks/CallbackManager.js";
|
||||
@@ -426,14 +426,17 @@ export class VectorIndexRetriever implements BaseRetriever {
|
||||
this.imageSimilarityTopK = imageSimilarityTopK ?? DEFAULT_SIMILARITY_TOP_K;
|
||||
}
|
||||
|
||||
async retrieve(
|
||||
query: string,
|
||||
parentEvent?: Event,
|
||||
preFilters?: MetadataFilters,
|
||||
): Promise<NodeWithScore[]> {
|
||||
let nodesWithScores = await this.textRetrieve(query, preFilters);
|
||||
async retrieve({
|
||||
query,
|
||||
parentEvent,
|
||||
preFilters,
|
||||
}: RetrieveParams): Promise<NodeWithScore[]> {
|
||||
let nodesWithScores = await this.textRetrieve(
|
||||
query,
|
||||
preFilters as MetadataFilters,
|
||||
);
|
||||
nodesWithScores = nodesWithScores.concat(
|
||||
await this.textToImageRetrieve(query, preFilters),
|
||||
await this.textToImageRetrieve(query, preFilters as MetadataFilters),
|
||||
);
|
||||
this.sendEvent(query, nodesWithScores, parentEvent);
|
||||
return nodesWithScores;
|
||||
|
||||
@@ -69,7 +69,7 @@ export class ObjectRetriever {
|
||||
|
||||
// Translating the retrieve method
|
||||
async retrieve(strOrQueryBundle: QueryType): Promise<any> {
|
||||
const nodes = await this.retriever.retrieve(strOrQueryBundle);
|
||||
const nodes = await this.retriever.retrieve({ query: strOrQueryBundle });
|
||||
const objs = nodes.map((n) => this._objectNodeMapping.fromNode(n.node));
|
||||
return objs;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import {
|
||||
IndexDict,
|
||||
IndexList,
|
||||
IndexStruct,
|
||||
IndexStructType,
|
||||
MetadataMode,
|
||||
TextNode,
|
||||
jsonToIndexStruct,
|
||||
} from "llamaindex";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("jsonToIndexStruct", () => {
|
||||
it("transforms json to IndexDict", () => {
|
||||
function isIndexDict(some: IndexStruct): some is IndexDict {
|
||||
return "type" in some && some.type === IndexStructType.SIMPLE_DICT;
|
||||
}
|
||||
|
||||
const node = new TextNode({ text: "text", id_: "nodeId" });
|
||||
const expected = new IndexDict();
|
||||
expected.addNode(node);
|
||||
|
||||
console.log("expected.toJson()", expected.toJson());
|
||||
const actual = jsonToIndexStruct(expected.toJson());
|
||||
|
||||
expect(isIndexDict(actual)).toBe(true);
|
||||
expect(
|
||||
(actual as IndexDict).nodesDict.nodeId.getContent(MetadataMode.NONE),
|
||||
).toEqual("text");
|
||||
});
|
||||
it("transforms json to IndexList", () => {
|
||||
function isIndexList(some: IndexStruct): some is IndexList {
|
||||
return "type" in some && some.type === IndexStructType.LIST;
|
||||
}
|
||||
|
||||
const node = new TextNode({ text: "text", id_: "nodeId" });
|
||||
const expected = new IndexList();
|
||||
expected.addNode(node);
|
||||
|
||||
const actual = jsonToIndexStruct(expected.toJson());
|
||||
|
||||
expect(isIndexList(actual)).toBe(true);
|
||||
expect((actual as IndexList).nodes[0]).toEqual("nodeId");
|
||||
});
|
||||
it("fails for unknown index type", () => {
|
||||
expect(() => {
|
||||
const json = {
|
||||
indexId: "dd120b16-8dce-4ce3-9bb6-15ca87fe4a1d",
|
||||
summary: undefined,
|
||||
nodesDict: {},
|
||||
type: "FOO",
|
||||
};
|
||||
return jsonToIndexStruct(json);
|
||||
}).toThrowError("Unknown index struct type: FOO");
|
||||
});
|
||||
it("fails for unknown node type", () => {
|
||||
expect(() => {
|
||||
const json = {
|
||||
indexId: "dd120b16-8dce-4ce3-9bb6-15ca87fe4a1d",
|
||||
summary: undefined,
|
||||
nodesDict: {
|
||||
nodeId: {
|
||||
...new TextNode({ text: "text", id_: "nodeId" }).toJSON(),
|
||||
type: "BAR",
|
||||
},
|
||||
},
|
||||
type: IndexStructType.SIMPLE_DICT,
|
||||
};
|
||||
return jsonToIndexStruct(json);
|
||||
}).toThrowError("Invalid node type: BAR");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"root": false,
|
||||
"rules": {
|
||||
"turbo/no-undeclared-env-vars": [
|
||||
"error",
|
||||
{
|
||||
"allowList": [
|
||||
"OPENAI_API_KEY",
|
||||
"LLAMA_CLOUD_API_KEY",
|
||||
"npm_config_user_agent",
|
||||
"http_proxy",
|
||||
"https_proxy",
|
||||
"MODEL",
|
||||
"NEXT_PUBLIC_CHAT_API",
|
||||
"NEXT_PUBLIC_MODEL"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,20 @@
|
||||
# create-llama
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 89a49f4: Add more config variables to .env file
|
||||
- fdf48dd: Add "Start in VSCode" option to postInstallAction
|
||||
- fdf48dd: Add devcontainers to generated code
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2d29350: Add LlamaParse option when selecting a pdf file or a folder (FastAPI only)
|
||||
- b354f23: Add embedding model option to create-llama (FastAPI only)
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -11,6 +11,7 @@ import fs from "fs";
|
||||
import terminalLink from "terminal-link";
|
||||
import type { InstallTemplateArgs } from "./helpers";
|
||||
import { installTemplate } from "./helpers";
|
||||
import { writeDevcontainer } from "./helpers/devcontainer";
|
||||
import { templatesDir } from "./helpers/dir";
|
||||
import { toolsRequireConfig } from "./helpers/tools";
|
||||
|
||||
@@ -34,6 +35,7 @@ export async function createApp({
|
||||
openAiKey,
|
||||
llamaCloudKey,
|
||||
model,
|
||||
embeddingModel,
|
||||
communityProjectPath,
|
||||
llamapack,
|
||||
vectorDb,
|
||||
@@ -80,6 +82,7 @@ export async function createApp({
|
||||
openAiKey,
|
||||
llamaCloudKey,
|
||||
model,
|
||||
embeddingModel,
|
||||
communityProjectPath,
|
||||
llamapack,
|
||||
vectorDb,
|
||||
@@ -110,7 +113,7 @@ export async function createApp({
|
||||
path.join(root, "README.md"),
|
||||
);
|
||||
} else {
|
||||
await installTemplate({ ...args, backend: true, forBackend: framework });
|
||||
await installTemplate({ ...args, backend: true });
|
||||
}
|
||||
|
||||
process.chdir(root);
|
||||
@@ -119,6 +122,8 @@ export async function createApp({
|
||||
console.log();
|
||||
}
|
||||
|
||||
await writeDevcontainer(root, templatesDir, framework, frontend);
|
||||
|
||||
if (toolsRequireConfig(tools)) {
|
||||
console.log(
|
||||
yellow(
|
||||
|
||||
@@ -91,17 +91,19 @@ for (const templateType of templateTypes) {
|
||||
test.skip(appType === "--no-frontend");
|
||||
await page.goto(`http://localhost:${port}`);
|
||||
await page.fill("form input", "hello");
|
||||
await page.click("form button[type=submit]");
|
||||
const response = await page.waitForResponse(
|
||||
(res) => {
|
||||
return (
|
||||
res.url().includes("/api/chat") && res.status() === 200
|
||||
);
|
||||
},
|
||||
{
|
||||
timeout: 1000 * 60,
|
||||
},
|
||||
);
|
||||
const [response] = await Promise.all([
|
||||
page.waitForResponse(
|
||||
(res) => {
|
||||
return (
|
||||
res.url().includes("/api/chat") && res.status() === 200
|
||||
);
|
||||
},
|
||||
{
|
||||
timeout: 1000 * 60,
|
||||
},
|
||||
),
|
||||
page.click("form button[type=submit]"),
|
||||
]);
|
||||
const text = await response.text();
|
||||
console.log("AI response when submitting message: ", text);
|
||||
expect(response.ok()).toBeTruthy();
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
|
||||
export type AppType = "--frontend" | "--no-frontend" | "";
|
||||
const MODEL = "gpt-3.5-turbo";
|
||||
const EMBEDDING_MODEL = "text-embedding-ada-002";
|
||||
export type CreateLlamaResult = {
|
||||
projectName: string;
|
||||
appProcess: ChildProcess;
|
||||
@@ -106,6 +107,8 @@ export async function runCreateLlama(
|
||||
vectorDb,
|
||||
"--model",
|
||||
MODEL,
|
||||
"--embedding-model",
|
||||
EMBEDDING_MODEL,
|
||||
"--open-ai-key",
|
||||
process.env.OPENAI_API_KEY || "testKey",
|
||||
appType,
|
||||
@@ -119,6 +122,7 @@ export async function runCreateLlama(
|
||||
postInstallAction,
|
||||
"--tools",
|
||||
"none",
|
||||
"--no-llama-parse",
|
||||
].join(" ");
|
||||
console.log(`running command '${command}' in ${cwd}`);
|
||||
const appProcess = exec(command, {
|
||||
@@ -171,7 +175,7 @@ export async function runCreateLlama(
|
||||
}
|
||||
|
||||
export async function createTestDir() {
|
||||
const cwd = path.join(__dirname, ".cache", crypto.randomUUID());
|
||||
const cwd = path.join(__dirname, "cache", crypto.randomUUID());
|
||||
await mkdir(cwd, { recursive: true });
|
||||
return cwd;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { TemplateFramework } from "./types";
|
||||
|
||||
function renderDevcontainerContent(
|
||||
templatesDir: string,
|
||||
framework: TemplateFramework,
|
||||
frontend: boolean,
|
||||
) {
|
||||
const devcontainerJson: any = JSON.parse(
|
||||
fs.readFileSync(path.join(templatesDir, "devcontainer.json"), "utf8"),
|
||||
);
|
||||
|
||||
// Modify postCreateCommand
|
||||
if (frontend) {
|
||||
devcontainerJson.postCreateCommand =
|
||||
framework === "fastapi"
|
||||
? "cd backend && poetry install && cd ../frontend && npm install"
|
||||
: "cd backend && npm install && cd ../frontend && npm install";
|
||||
} else {
|
||||
devcontainerJson.postCreateCommand =
|
||||
framework === "fastapi" ? "poetry install" : "npm install";
|
||||
}
|
||||
|
||||
// Modify containerEnv
|
||||
if (framework === "fastapi") {
|
||||
if (frontend) {
|
||||
devcontainerJson.containerEnv = {
|
||||
...devcontainerJson.containerEnv,
|
||||
PYTHONPATH: "${PYTHONPATH}:${workspaceFolder}/backend",
|
||||
};
|
||||
} else {
|
||||
devcontainerJson.containerEnv = {
|
||||
...devcontainerJson.containerEnv,
|
||||
PYTHONPATH: "${PYTHONPATH}:${workspaceFolder}",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(devcontainerJson, null, 2);
|
||||
}
|
||||
|
||||
export const writeDevcontainer = async (
|
||||
root: string,
|
||||
templatesDir: string,
|
||||
framework: TemplateFramework,
|
||||
frontend: boolean,
|
||||
) => {
|
||||
console.log("Adding .devcontainer");
|
||||
const devcontainerContent = renderDevcontainerContent(
|
||||
templatesDir,
|
||||
framework,
|
||||
frontend,
|
||||
);
|
||||
const devcontainerDir = path.join(root, ".devcontainer");
|
||||
fs.mkdirSync(devcontainerDir);
|
||||
await fs.promises.writeFile(
|
||||
path.join(devcontainerDir, "devcontainer.json"),
|
||||
devcontainerContent,
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,241 @@
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import {
|
||||
FileSourceConfig,
|
||||
TemplateDataSource,
|
||||
TemplateFramework,
|
||||
TemplateVectorDB,
|
||||
} from "./types";
|
||||
|
||||
type EnvVar = {
|
||||
name?: string;
|
||||
description?: string;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
const renderEnvVar = (envVars: EnvVar[]): string => {
|
||||
return envVars.reduce(
|
||||
(prev, env) =>
|
||||
prev +
|
||||
(env.description
|
||||
? `# ${env.description.replaceAll("\n", "\n# ")}\n`
|
||||
: "") +
|
||||
(env.name
|
||||
? env.value
|
||||
? `${env.name}=${env.value}\n\n`
|
||||
: `# ${env.name}=\n\n`
|
||||
: ""),
|
||||
"",
|
||||
);
|
||||
};
|
||||
|
||||
const getVectorDBEnvs = (vectorDb: TemplateVectorDB) => {
|
||||
switch (vectorDb) {
|
||||
case "mongo":
|
||||
return [
|
||||
{
|
||||
name: "MONGO_URI",
|
||||
description:
|
||||
"For generating a connection URI, see https://docs.timescale.com/use-timescale/latest/services/create-a-service\nThe MongoDB connection URI.",
|
||||
},
|
||||
{
|
||||
name: "MONGODB_DATABASE",
|
||||
},
|
||||
{
|
||||
name: "MONGODB_VECTORS",
|
||||
},
|
||||
{
|
||||
name: "MONGODB_VECTOR_INDEX",
|
||||
},
|
||||
];
|
||||
case "pg":
|
||||
return [
|
||||
{
|
||||
name: "PG_CONNECTION_STRING",
|
||||
description:
|
||||
"For generating a connection URI, see https://docs.timescale.com/use-timescale/latest/services/create-a-service\nThe PostgreSQL connection string.",
|
||||
},
|
||||
];
|
||||
|
||||
case "pinecone":
|
||||
return [
|
||||
{
|
||||
name: "PINECONE_API_KEY",
|
||||
description:
|
||||
"Configuration for Pinecone vector store\nThe Pinecone API key.",
|
||||
},
|
||||
{
|
||||
name: "PINECONE_ENVIRONMENT",
|
||||
},
|
||||
{
|
||||
name: "PINECONE_INDEX_NAME",
|
||||
},
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const getDataSourceEnvs = (dataSource: TemplateDataSource) => {
|
||||
switch (dataSource.type) {
|
||||
case "web":
|
||||
return [
|
||||
{
|
||||
name: "BASE_URL",
|
||||
description: "The base URL to start web scraping.",
|
||||
},
|
||||
{
|
||||
name: "URL_PREFIX",
|
||||
description: "The prefix of the URL to start web scraping.",
|
||||
},
|
||||
{
|
||||
name: "MAX_DEPTH",
|
||||
description: "The maximum depth to scrape.",
|
||||
},
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const createBackendEnvFile = async (
|
||||
root: string,
|
||||
opts: {
|
||||
openAiKey?: string;
|
||||
llamaCloudKey?: string;
|
||||
vectorDb?: TemplateVectorDB;
|
||||
model?: string;
|
||||
embeddingModel?: string;
|
||||
framework?: TemplateFramework;
|
||||
dataSource?: TemplateDataSource;
|
||||
port?: number;
|
||||
},
|
||||
) => {
|
||||
// Init env values
|
||||
const envFileName = ".env";
|
||||
const defaultEnvs = [
|
||||
{
|
||||
render: true,
|
||||
name: "MODEL",
|
||||
description: "The name of LLM model to use.",
|
||||
value: opts.model || "gpt-3.5-turbo",
|
||||
},
|
||||
{
|
||||
render: true,
|
||||
name: "OPENAI_API_KEY",
|
||||
description: "The OpenAI API key to use.",
|
||||
value: opts.openAiKey,
|
||||
},
|
||||
// Add vector database environment variables
|
||||
...(opts.vectorDb ? getVectorDBEnvs(opts.vectorDb) : []),
|
||||
// Add data source environment variables
|
||||
...(opts.dataSource ? getDataSourceEnvs(opts.dataSource) : []),
|
||||
];
|
||||
let envVars: EnvVar[] = [];
|
||||
if (opts.framework === "fastapi") {
|
||||
envVars = [
|
||||
...defaultEnvs,
|
||||
...[
|
||||
{
|
||||
name: "APP_HOST",
|
||||
description: "The address to start the backend app.",
|
||||
value: "0.0.0.0",
|
||||
},
|
||||
{
|
||||
name: "APP_PORT",
|
||||
description: "The port to start the backend app.",
|
||||
value: opts.port?.toString() || "8000",
|
||||
},
|
||||
{
|
||||
name: "EMBEDDING_MODEL",
|
||||
description: "Name of the embedding model to use.",
|
||||
value: opts.embeddingModel,
|
||||
},
|
||||
{
|
||||
name: "EMBEDDING_DIM",
|
||||
description: "Dimension of the embedding model to use.",
|
||||
},
|
||||
{
|
||||
name: "LLM_TEMPERATURE",
|
||||
description: "Temperature for sampling from the model.",
|
||||
},
|
||||
{
|
||||
name: "LLM_MAX_TOKENS",
|
||||
description: "Maximum number of tokens to generate.",
|
||||
},
|
||||
{
|
||||
name: "TOP_K",
|
||||
description:
|
||||
"The number of similar embeddings to return when retrieving documents.",
|
||||
value: "3",
|
||||
},
|
||||
{
|
||||
name: "SYSTEM_PROMPT",
|
||||
description: `Custom system prompt.
|
||||
Example:
|
||||
SYSTEM_PROMPT="
|
||||
We have provided context information below.
|
||||
---------------------
|
||||
{context_str}
|
||||
---------------------
|
||||
Given this information, please answer the question: {query_str}
|
||||
"`,
|
||||
},
|
||||
(opts?.dataSource?.config as FileSourceConfig).useLlamaParse
|
||||
? {
|
||||
name: "LLAMA_CLOUD_API_KEY",
|
||||
description: `The Llama Cloud API key.`,
|
||||
value: opts.llamaCloudKey,
|
||||
}
|
||||
: {},
|
||||
],
|
||||
];
|
||||
} else {
|
||||
envVars = [
|
||||
...defaultEnvs,
|
||||
...[
|
||||
opts.framework === "nextjs"
|
||||
? {
|
||||
name: "NEXT_PUBLIC_MODEL",
|
||||
description:
|
||||
"The LLM model to use (hardcode to front-end artifact).",
|
||||
}
|
||||
: {},
|
||||
],
|
||||
];
|
||||
}
|
||||
// Render and write env file
|
||||
const content = renderEnvVar(envVars);
|
||||
await fs.writeFile(path.join(root, envFileName), content);
|
||||
console.log(`Created '${envFileName}' file. Please check the settings.`);
|
||||
};
|
||||
|
||||
export const createFrontendEnvFile = async (
|
||||
root: string,
|
||||
opts: {
|
||||
customApiPath?: string;
|
||||
model?: string;
|
||||
},
|
||||
) => {
|
||||
const defaultFrontendEnvs = [
|
||||
{
|
||||
name: "MODEL",
|
||||
description: "The OpenAI model to use.",
|
||||
value: opts.model,
|
||||
},
|
||||
{
|
||||
name: "NEXT_PUBLIC_MODEL",
|
||||
description: "The OpenAI model to use (hardcode to front-end artifact).",
|
||||
value: opts.model,
|
||||
},
|
||||
{
|
||||
name: "NEXT_PUBLIC_CHAT_API",
|
||||
description: "The backend API for chat endpoint.",
|
||||
value: opts.customApiPath
|
||||
? opts.customApiPath
|
||||
: "http://localhost:8000/api/chat",
|
||||
},
|
||||
];
|
||||
const content = renderEnvVar(defaultFrontendEnvs);
|
||||
await fs.writeFile(path.join(root, ".env"), content);
|
||||
};
|
||||
@@ -7,6 +7,7 @@ import { cyan } from "picocolors";
|
||||
|
||||
import { COMMUNITY_OWNER, COMMUNITY_REPO } from "./constant";
|
||||
import { templatesDir } from "./dir";
|
||||
import { createBackendEnvFile, createFrontendEnvFile } from "./env-variables";
|
||||
import { PackageManager } from "./get-pkg-manager";
|
||||
import { installLlamapackProject } from "./llama-pack";
|
||||
import { isHavingPoetryLockFile, tryPoetryRun } from "./poetry";
|
||||
@@ -18,94 +19,37 @@ import {
|
||||
TemplateDataSource,
|
||||
TemplateFramework,
|
||||
TemplateVectorDB,
|
||||
WebSourceConfig,
|
||||
} from "./types";
|
||||
import { installTSTemplate } from "./typescript";
|
||||
|
||||
const createEnvLocalFile = async (
|
||||
root: string,
|
||||
opts?: {
|
||||
openAiKey?: string;
|
||||
llamaCloudKey?: string;
|
||||
vectorDb?: TemplateVectorDB;
|
||||
model?: string;
|
||||
framework?: TemplateFramework;
|
||||
dataSource?: TemplateDataSource;
|
||||
},
|
||||
) => {
|
||||
const envFileName = ".env";
|
||||
let content = "";
|
||||
|
||||
const model = opts?.model || "gpt-3.5-turbo";
|
||||
content += `MODEL=${model}\n`;
|
||||
if (opts?.framework === "nextjs") {
|
||||
content += `NEXT_PUBLIC_MODEL=${model}\n`;
|
||||
}
|
||||
console.log("\nUsing OpenAI model: ", model, "\n");
|
||||
|
||||
if (opts?.openAiKey) {
|
||||
content += `OPENAI_API_KEY=${opts?.openAiKey}\n`;
|
||||
}
|
||||
|
||||
if (opts?.llamaCloudKey) {
|
||||
content += `LLAMA_CLOUD_API_KEY=${opts?.llamaCloudKey}\n`;
|
||||
}
|
||||
|
||||
switch (opts?.vectorDb) {
|
||||
case "mongo": {
|
||||
content += `# For generating a connection URI, see https://www.mongodb.com/docs/guides/atlas/connection-string\n`;
|
||||
content += `MONGO_URI=\n`;
|
||||
content += `MONGODB_DATABASE=\n`;
|
||||
content += `MONGODB_VECTORS=\n`;
|
||||
content += `MONGODB_VECTOR_INDEX=\n`;
|
||||
break;
|
||||
}
|
||||
case "pg": {
|
||||
content += `# For generating a connection URI, see https://docs.timescale.com/use-timescale/latest/services/create-a-service\n`;
|
||||
content += `PG_CONNECTION_STRING=\n`;
|
||||
break;
|
||||
}
|
||||
case "pinecone": {
|
||||
content += `PINECONE_API_KEY=\n`;
|
||||
content += `PINECONE_ENVIRONMENT=\n`;
|
||||
content += `PINECONE_INDEX_NAME=\n`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (opts?.dataSource?.type) {
|
||||
case "web": {
|
||||
const webConfig = opts?.dataSource.config as WebSourceConfig;
|
||||
content += `# web loader config\n`;
|
||||
content += `BASE_URL=${webConfig.baseUrl}\n`;
|
||||
content += `URL_PREFIX=${webConfig.baseUrl}\n`;
|
||||
content += `MAX_DEPTH=${webConfig.depth}\n`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (content) {
|
||||
await fs.writeFile(path.join(root, envFileName), content);
|
||||
console.log(`Created '${envFileName}' file. Please check the settings.`);
|
||||
}
|
||||
};
|
||||
|
||||
const generateContextData = async (
|
||||
// eslint-disable-next-line max-params
|
||||
async function generateContextData(
|
||||
framework: TemplateFramework,
|
||||
packageManager?: PackageManager,
|
||||
openAiKey?: string,
|
||||
vectorDb?: TemplateVectorDB,
|
||||
) => {
|
||||
dataSource?: TemplateDataSource,
|
||||
llamaCloudKey?: string,
|
||||
) {
|
||||
if (packageManager) {
|
||||
const runGenerate = `${cyan(
|
||||
framework === "fastapi"
|
||||
? "poetry run python app/engine/generate.py"
|
||||
: `${packageManager} run generate`,
|
||||
)}`;
|
||||
const hasOpenAiKey = openAiKey || process.env["OPENAI_API_KEY"];
|
||||
const openAiKeyConfigured = openAiKey || process.env["OPENAI_API_KEY"];
|
||||
const llamaCloudKeyConfigured = (dataSource?.config as FileSourceConfig)
|
||||
?.useLlamaParse
|
||||
? llamaCloudKey || process.env["LLAMA_CLOUD_API_KEY"]
|
||||
: true;
|
||||
const hasVectorDb = vectorDb && vectorDb !== "none";
|
||||
if (framework === "fastapi") {
|
||||
if (hasOpenAiKey && !hasVectorDb && isHavingPoetryLockFile()) {
|
||||
if (
|
||||
openAiKeyConfigured &&
|
||||
llamaCloudKeyConfigured &&
|
||||
!hasVectorDb &&
|
||||
isHavingPoetryLockFile()
|
||||
) {
|
||||
console.log(`Running ${runGenerate} to generate the context data.`);
|
||||
const result = tryPoetryRun("python app/engine/generate.py");
|
||||
if (!result) {
|
||||
@@ -116,7 +60,7 @@ const generateContextData = async (
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (hasOpenAiKey && vectorDb === "none") {
|
||||
if (openAiKeyConfigured && vectorDb === "none") {
|
||||
console.log(`Running ${runGenerate} to generate the context data.`);
|
||||
await callPackageManager(packageManager, true, ["run", "generate"]);
|
||||
return;
|
||||
@@ -124,14 +68,15 @@ const generateContextData = async (
|
||||
}
|
||||
|
||||
const settings = [];
|
||||
if (!hasOpenAiKey) settings.push("your OpenAI key");
|
||||
if (!openAiKeyConfigured) settings.push("your OpenAI key");
|
||||
if (!llamaCloudKeyConfigured) settings.push("your Llama Cloud key");
|
||||
if (hasVectorDb) settings.push("your Vector DB environment variables");
|
||||
const settingsMessage =
|
||||
settings.length > 0 ? `After setting ${settings.join(" and ")}, ` : "";
|
||||
const generateMessage = `run ${runGenerate} to generate the context data.`;
|
||||
console.log(`\n${settingsMessage}${generateMessage}\n\n`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const copyContextData = async (
|
||||
root: string,
|
||||
@@ -208,13 +153,15 @@ export const installTemplate = async (
|
||||
// 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.
|
||||
await createEnvLocalFile(props.root, {
|
||||
await createBackendEnvFile(props.root, {
|
||||
openAiKey: props.openAiKey,
|
||||
llamaCloudKey: props.llamaCloudKey,
|
||||
vectorDb: props.vectorDb,
|
||||
model: props.model,
|
||||
embeddingModel: props.embeddingModel,
|
||||
framework: props.framework,
|
||||
dataSource: props.dataSource,
|
||||
port: props.externalPort,
|
||||
});
|
||||
|
||||
if (props.engine === "context") {
|
||||
@@ -228,13 +175,17 @@ export const installTemplate = async (
|
||||
props.packageManager,
|
||||
props.openAiKey,
|
||||
props.vectorDb,
|
||||
props.dataSource,
|
||||
props.llamaCloudKey,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// this is a frontend for a full-stack app, create .env file with model information
|
||||
const content = `MODEL=${props.model}\nNEXT_PUBLIC_MODEL=${props.model}\n`;
|
||||
await fs.writeFile(path.join(props.root, ".env"), content);
|
||||
createFrontendEnvFile(props.root, {
|
||||
model: props.model,
|
||||
customApiPath: props.customApiPath,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ export const installLlamapackProject = async ({
|
||||
await copyLlamapackEmptyProject({ root });
|
||||
await copyData({ root });
|
||||
await installLlamapackExample({ root, llamapack });
|
||||
if (postInstallAction !== "none") {
|
||||
if (postInstallAction === "runApp" || postInstallAction === "dependencies") {
|
||||
installPythonDependencies({ noRoot: true });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -266,7 +266,7 @@ export const installPythonTemplate = async ({
|
||||
);
|
||||
await addDependencies(root, addOnDependencies);
|
||||
|
||||
if (postInstallAction !== "none") {
|
||||
if (postInstallAction === "runApp" || postInstallAction === "dependencies") {
|
||||
installPythonDependencies();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,7 +6,11 @@ export type TemplateFramework = "nextjs" | "express" | "fastapi";
|
||||
export type TemplateEngine = "simple" | "context";
|
||||
export type TemplateUI = "html" | "shadcn";
|
||||
export type TemplateVectorDB = "none" | "mongo" | "pg" | "pinecone";
|
||||
export type TemplatePostInstallAction = "none" | "dependencies" | "runApp";
|
||||
export type TemplatePostInstallAction =
|
||||
| "none"
|
||||
| "VSCode"
|
||||
| "dependencies"
|
||||
| "runApp";
|
||||
export type TemplateDataSource = {
|
||||
type: TemplateDataSourceType;
|
||||
config: TemplateDataSourceConfig;
|
||||
@@ -37,8 +41,8 @@ export interface InstallTemplateArgs {
|
||||
customApiPath?: string;
|
||||
openAiKey?: string;
|
||||
llamaCloudKey?: string;
|
||||
forBackend?: string;
|
||||
model: string;
|
||||
embeddingModel: string;
|
||||
communityProjectPath?: string;
|
||||
llamapack?: string;
|
||||
vectorDb?: TemplateVectorDB;
|
||||
|
||||
@@ -61,10 +61,10 @@ export const installTSTemplate = async ({
|
||||
ui,
|
||||
eslint,
|
||||
customApiPath,
|
||||
forBackend,
|
||||
vectorDb,
|
||||
postInstallAction,
|
||||
}: InstallTemplateArgs) => {
|
||||
backend,
|
||||
}: InstallTemplateArgs & { backend: boolean }) => {
|
||||
console.log(bold(`Using ${packageManager}.`));
|
||||
|
||||
/**
|
||||
@@ -82,23 +82,20 @@ export const installTSTemplate = async ({
|
||||
});
|
||||
|
||||
/**
|
||||
* If the backend is next.js, rename next.config.app.js to next.config.js
|
||||
* If not, rename next.config.static.js to next.config.js
|
||||
* If next.js is not used as a backend, update next.config.js to use static site generation.
|
||||
*/
|
||||
if (framework == "nextjs" && forBackend === "nextjs") {
|
||||
const nextConfigAppPath = path.join(root, "next.config.app.js");
|
||||
const nextConfigPath = path.join(root, "next.config.js");
|
||||
await fs.rename(nextConfigAppPath, nextConfigPath);
|
||||
// delete next.config.static.js
|
||||
const nextConfigStaticPath = path.join(root, "next.config.static.js");
|
||||
await fs.rm(nextConfigStaticPath);
|
||||
} else if (framework == "nextjs" && typeof forBackend === "undefined") {
|
||||
const nextConfigStaticPath = path.join(root, "next.config.static.js");
|
||||
const nextConfigPath = path.join(root, "next.config.js");
|
||||
await fs.rename(nextConfigStaticPath, nextConfigPath);
|
||||
// delete next.config.app.js
|
||||
const nextConfigAppPath = path.join(root, "next.config.app.js");
|
||||
await fs.rm(nextConfigAppPath);
|
||||
if (framework === "nextjs" && !backend) {
|
||||
// update next.config.json for static site generation
|
||||
const nextConfigJsonFile = path.join(root, "next.config.json");
|
||||
const nextConfigJson: any = JSON.parse(
|
||||
await fs.readFile(nextConfigJsonFile, "utf8"),
|
||||
);
|
||||
nextConfigJson.output = "export";
|
||||
nextConfigJson.images = { unoptimized: true };
|
||||
await fs.writeFile(
|
||||
nextConfigJsonFile,
|
||||
JSON.stringify(nextConfigJson, null, 2) + os.EOL,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,10 +171,6 @@ export const installTSTemplate = async ({
|
||||
const apiPath = path.join(root, "app", "api");
|
||||
await fs.rm(apiPath, { recursive: true });
|
||||
// modify the dev script to use the custom api path
|
||||
packageJson.scripts = {
|
||||
...packageJson.scripts,
|
||||
dev: `cross-env NEXT_PUBLIC_CHAT_API=${customApiPath} next dev`,
|
||||
};
|
||||
}
|
||||
|
||||
if (engine === "context" && relativeEngineDestPath) {
|
||||
@@ -228,7 +221,7 @@ export const installTSTemplate = async ({
|
||||
JSON.stringify(packageJson, null, 2) + os.EOL,
|
||||
);
|
||||
|
||||
if (postInstallAction !== "none") {
|
||||
if (postInstallAction === "runApp" || postInstallAction === "dependencies") {
|
||||
await installTSDependencies(packageJson, packageManager, isOnline);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#!/usr/bin/env node
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { execSync } from "child_process";
|
||||
import Commander from "commander";
|
||||
import Conf from "conf";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { bold, cyan, green, red, yellow } from "picocolors";
|
||||
import prompts from "prompts";
|
||||
import terminalLink from "terminal-link";
|
||||
import checkForUpdate from "update-check";
|
||||
import { createApp } from "./create-app";
|
||||
import { getPkgManager } from "./helpers/get-pkg-manager";
|
||||
@@ -119,6 +121,12 @@ const program = new Commander.Command(packageJson.name)
|
||||
`
|
||||
|
||||
Select OpenAI model to use. E.g. gpt-3.5-turbo.
|
||||
`,
|
||||
)
|
||||
.option(
|
||||
"--embedding-model <embeddingModel>",
|
||||
`
|
||||
Select OpenAI embedding model to use. E.g. text-embedding-ada-002.
|
||||
`,
|
||||
)
|
||||
.option(
|
||||
@@ -281,6 +289,7 @@ async function run(): Promise<void> {
|
||||
openAiKey: program.openAiKey,
|
||||
llamaCloudKey: program.llamaCloudKey,
|
||||
model: program.model,
|
||||
embeddingModel: program.embeddingModel,
|
||||
communityProjectPath: program.communityProjectPath,
|
||||
llamapack: program.llamapack,
|
||||
vectorDb: program.vectorDb,
|
||||
@@ -291,7 +300,31 @@ async function run(): Promise<void> {
|
||||
});
|
||||
conf.set("preferences", preferences);
|
||||
|
||||
if (program.postInstallAction === "runApp") {
|
||||
if (program.postInstallAction === "VSCode") {
|
||||
console.log(`Starting VSCode in ${root}...`);
|
||||
try {
|
||||
execSync(`code . --new-window --goto README.md`, {
|
||||
stdio: "inherit",
|
||||
cwd: root,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(
|
||||
red(
|
||||
`Failed to start VSCode in ${root}.
|
||||
Got error: ${(error as Error).message}.\n`,
|
||||
),
|
||||
);
|
||||
console.log(
|
||||
`Make sure you have VSCode installed and added to your PATH.
|
||||
Please check ${cyan(
|
||||
terminalLink(
|
||||
"This documentation",
|
||||
`https://code.visualstudio.com/docs/setup/setup-overview`,
|
||||
),
|
||||
)} for more information.`,
|
||||
);
|
||||
}
|
||||
} else if (program.postInstallAction === "runApp") {
|
||||
console.log(`Running app in ${root}...`);
|
||||
await runApp(
|
||||
root,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-llama",
|
||||
"version": "0.0.26",
|
||||
"version": "0.0.28",
|
||||
"keywords": [
|
||||
"rag",
|
||||
"llamaindex",
|
||||
@@ -23,7 +23,7 @@
|
||||
"clean": "rimraf --glob ./dist ./templates/**/__pycache__ ./templates/**/node_modules ./templates/**/poetry.lock",
|
||||
"dev": "ncc build ./index.ts -w -o dist/",
|
||||
"build": "npm run clean && ncc build ./index.ts -o ./dist/ --minify --no-cache --no-source-map-register",
|
||||
"lint": "eslint . --ignore-pattern dist",
|
||||
"lint": "eslint . --ignore-pattern dist --ignore-pattern e2e/cache",
|
||||
"e2e": "playwright test",
|
||||
"prepublishOnly": "cd ../../ && pnpm run build:release"
|
||||
},
|
||||
|
||||
@@ -69,6 +69,7 @@ const defaults: QuestionArgs = {
|
||||
openAiKey: "",
|
||||
llamaCloudKey: "",
|
||||
model: "gpt-3.5-turbo",
|
||||
embeddingModel: "text-embedding-ada-002",
|
||||
communityProjectPath: "",
|
||||
llamapack: "",
|
||||
postInstallAction: "dependencies",
|
||||
@@ -214,18 +215,30 @@ export const askQuestions = async (
|
||||
title: "Just generate code (~1 sec)",
|
||||
value: "none",
|
||||
},
|
||||
{
|
||||
title: "Start in VSCode (~1 sec)",
|
||||
value: "VSCode",
|
||||
},
|
||||
{
|
||||
title: "Generate code and install dependencies (~2 min)",
|
||||
value: "dependencies",
|
||||
},
|
||||
];
|
||||
|
||||
const hasOpenAiKey = program.openAiKey || process.env["OPENAI_API_KEY"];
|
||||
const openAiKeyConfigured =
|
||||
program.openAiKey || process.env["OPENAI_API_KEY"];
|
||||
// If using LlamaParse, require LlamaCloud API key
|
||||
const llamaCloudKeyConfigured = (
|
||||
program.dataSource?.config as FileSourceConfig
|
||||
)?.useLlamaParse
|
||||
? program.llamaCloudKey || process.env["LLAMA_CLOUD_API_KEY"]
|
||||
: true;
|
||||
const hasVectorDb = program.vectorDb && program.vectorDb !== "none";
|
||||
// Can run the app if all tools do not require configuration
|
||||
if (
|
||||
!hasVectorDb &&
|
||||
hasOpenAiKey &&
|
||||
openAiKeyConfigured &&
|
||||
llamaCloudKeyConfigured &&
|
||||
!toolsRequireConfig(program.tools) &&
|
||||
!program.llamapack
|
||||
) {
|
||||
@@ -443,6 +456,38 @@ export const askQuestions = async (
|
||||
}
|
||||
}
|
||||
|
||||
if (!program.embeddingModel && program.framework === "fastapi") {
|
||||
if (ciInfo.isCI) {
|
||||
program.embeddingModel = getPrefOrDefault("embeddingModel");
|
||||
} else {
|
||||
const { embeddingModel } = await prompts(
|
||||
{
|
||||
type: "select",
|
||||
name: "embeddingModel",
|
||||
message: "Which embedding model would you like to use?",
|
||||
choices: [
|
||||
{
|
||||
title: "text-embedding-ada-002",
|
||||
value: "text-embedding-ada-002",
|
||||
},
|
||||
{
|
||||
title: "text-embedding-3-small",
|
||||
value: "text-embedding-3-small",
|
||||
},
|
||||
{
|
||||
title: "text-embedding-3-large",
|
||||
value: "text-embedding-3-large",
|
||||
},
|
||||
],
|
||||
initial: 0,
|
||||
},
|
||||
handlers,
|
||||
);
|
||||
program.embeddingModel = embeddingModel;
|
||||
preferences.embeddingModel = embeddingModel;
|
||||
}
|
||||
}
|
||||
|
||||
if (program.files) {
|
||||
// If user specified files option, then the program should use context engine
|
||||
program.engine == "context";
|
||||
@@ -527,8 +572,9 @@ export const askQuestions = async (
|
||||
}
|
||||
|
||||
if (
|
||||
program.dataSource?.type === "file" ||
|
||||
(program.dataSource?.type === "folder" && program.framework === "fastapi")
|
||||
(program.dataSource?.type === "file" ||
|
||||
program.dataSource?.type === "folder") &&
|
||||
program.framework === "fastapi"
|
||||
) {
|
||||
if (ciInfo.isCI) {
|
||||
program.llamaCloudKey = getPrefOrDefault("llamaCloudKey");
|
||||
@@ -571,11 +617,8 @@ export const askQuestions = async (
|
||||
{
|
||||
type: "text",
|
||||
name: "llamaCloudKey",
|
||||
message: "Please provide your LlamaIndex Cloud API key:",
|
||||
validate: (value) =>
|
||||
value
|
||||
? true
|
||||
: "LlamaIndex Cloud API key is required. You can get it from: https://cloud.llamaindex.ai/api-key",
|
||||
message:
|
||||
"Please provide your LlamaIndex Cloud API key (leave blank to skip):",
|
||||
},
|
||||
handlers,
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
from llama_index.core.settings import Settings
|
||||
from llama_index.core.agent import AgentRunner
|
||||
from llama_index.core.tools.query_engine import QueryEngineTool
|
||||
@@ -6,11 +7,13 @@ from app.engine.index import get_index
|
||||
|
||||
|
||||
def get_chat_engine():
|
||||
system_prompt = os.getenv("SYSTEM_PROMPT")
|
||||
top_k = os.getenv("TOP_K", "3")
|
||||
tools = []
|
||||
|
||||
# Add query tool
|
||||
index = get_index()
|
||||
query_engine = index.as_query_engine(similarity_top_k=3)
|
||||
query_engine = index.as_query_engine(similarity_top_k=int(top_k))
|
||||
query_engine_tool = QueryEngineTool.from_defaults(query_engine=query_engine)
|
||||
tools.append(query_engine_tool)
|
||||
|
||||
@@ -20,5 +23,6 @@ def get_chat_engine():
|
||||
return AgentRunner.from_llm(
|
||||
llm=Settings.llm,
|
||||
tools=tools,
|
||||
system_prompt=system_prompt,
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import os
|
||||
from app.engine.index import get_index
|
||||
|
||||
|
||||
def get_chat_engine():
|
||||
system_prompt = os.getenv("SYSTEM_PROMPT")
|
||||
top_k = os.getenv("TOP_K", 3)
|
||||
|
||||
return get_index().as_chat_engine(
|
||||
similarity_top_k=3, chat_mode="condense_plus_context"
|
||||
similarity_top_k=int(top_k),
|
||||
system_prompt=system_prompt,
|
||||
chat_mode="condense_plus_context",
|
||||
)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
from llama_parse import LlamaParse
|
||||
from llama_index.core import SimpleDirectoryReader
|
||||
|
||||
@@ -5,10 +6,12 @@ DATA_DIR = "data" # directory containing the documents
|
||||
|
||||
|
||||
def get_documents():
|
||||
parser = LlamaParse(
|
||||
result_type="markdown",
|
||||
verbose=True,
|
||||
)
|
||||
if os.getenv("LLAMA_CLOUD_API_KEY") is None:
|
||||
raise ValueError(
|
||||
"LLAMA_CLOUD_API_KEY environment variable is not set. "
|
||||
"Please set it in .env file or in your shell environment then run again!"
|
||||
)
|
||||
parser = LlamaParse(result_type="markdown", verbose=True, language="en")
|
||||
|
||||
reader = SimpleDirectoryReader(DATA_DIR, file_extractor={".pdf": parser})
|
||||
return reader.load_data()
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"image": "mcr.microsoft.com/vscode/devcontainers/typescript-node:dev-20-bullseye",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers-contrib/features/turborepo-npm:1": {},
|
||||
"ghcr.io/devcontainers-contrib/features/typescript:2": {},
|
||||
"ghcr.io/devcontainers/features/python:1": {
|
||||
"version": "3.11",
|
||||
"toolsToInstall": ["flake8", "black", "mypy", "poetry"]
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
"codespaces": {
|
||||
"openFiles": ["README.md"]
|
||||
},
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-vscode.typescript-language-features",
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-python.python",
|
||||
"ms-python.black-formatter",
|
||||
"ms-python.vscode-flake8",
|
||||
"ms-python.vscode-pylance"
|
||||
],
|
||||
"settings": {
|
||||
"python.formatting.provider": "black",
|
||||
"python.languageServer": "Pylance",
|
||||
"python.analysis.typeCheckingMode": "basic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"containerEnv": {
|
||||
"POETRY_VIRTUALENVS_CREATE": "false"
|
||||
},
|
||||
"forwardPorts": [3000, 8000]
|
||||
}
|
||||
@@ -1,10 +1,41 @@
|
||||
import os
|
||||
from llama_index.llms.openai import OpenAI
|
||||
from typing import Dict
|
||||
from llama_index.core.settings import Settings
|
||||
from llama_index.llms.openai import OpenAI
|
||||
from llama_index.embeddings.openai import OpenAIEmbedding
|
||||
|
||||
|
||||
def llm_config_from_env() -> Dict:
|
||||
from llama_index.core.constants import DEFAULT_TEMPERATURE
|
||||
|
||||
model = os.getenv("MODEL")
|
||||
temperature = os.getenv("LLM_TEMPERATURE", DEFAULT_TEMPERATURE)
|
||||
max_tokens = os.getenv("LLM_MAX_TOKENS")
|
||||
|
||||
config = {
|
||||
"model": model,
|
||||
"temperature": float(temperature),
|
||||
"max_tokens": int(max_tokens) if max_tokens is not None else None,
|
||||
}
|
||||
return config
|
||||
|
||||
|
||||
def embedding_config_from_env() -> Dict:
|
||||
model = os.getenv("EMBEDDING_MODEL")
|
||||
dimension = os.getenv("EMBEDDING_DIM")
|
||||
|
||||
config = {
|
||||
"model": model,
|
||||
"dimension": int(dimension) if dimension is not None else None,
|
||||
}
|
||||
return config
|
||||
|
||||
|
||||
def init_settings():
|
||||
model = os.getenv("MODEL", "gpt-3.5-turbo")
|
||||
Settings.llm = OpenAI(model=model)
|
||||
Settings.chunk_size = 1024
|
||||
Settings.chunk_overlap = 20
|
||||
llm_configs = llm_config_from_env()
|
||||
embedding_configs = embedding_config_from_env()
|
||||
|
||||
Settings.llm = OpenAI(**llm_configs)
|
||||
Settings.embed_model = OpenAIEmbedding(**embedding_configs)
|
||||
Settings.chunk_size = int(os.getenv("CHUNK_SIZE", "1024"))
|
||||
Settings.chunk_overlap = int(os.getenv("CHUNK_OVERLAP", "20"))
|
||||
|
||||
@@ -32,4 +32,7 @@ app.include_router(chat_router, prefix="/api/chat")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app="main:app", host="0.0.0.0", reload=True)
|
||||
app_host = os.getenv("APP_HOST", "0.0.0.0")
|
||||
app_port = int(os.getenv("APP_PORT", "8000"))
|
||||
|
||||
uvicorn.run(app="main:app", host=app_host, port=app_port, reload=True)
|
||||
|
||||
@@ -1,10 +1,41 @@
|
||||
import os
|
||||
from llama_index.llms.openai import OpenAI
|
||||
from typing import Dict
|
||||
from llama_index.core.settings import Settings
|
||||
from llama_index.llms.openai import OpenAI
|
||||
from llama_index.embeddings.openai import OpenAIEmbedding
|
||||
|
||||
|
||||
def llm_config_from_env() -> Dict:
|
||||
from llama_index.core.constants import DEFAULT_TEMPERATURE
|
||||
|
||||
model = os.getenv("MODEL")
|
||||
temperature = os.getenv("LLM_TEMPERATURE", DEFAULT_TEMPERATURE)
|
||||
max_tokens = os.getenv("LLM_MAX_TOKENS")
|
||||
|
||||
config = {
|
||||
"model": model,
|
||||
"temperature": float(temperature),
|
||||
"max_tokens": int(max_tokens) if max_tokens is not None else None,
|
||||
}
|
||||
return config
|
||||
|
||||
|
||||
def embedding_config_from_env() -> Dict:
|
||||
model = os.getenv("EMBEDDING_MODEL")
|
||||
dimension = os.getenv("EMBEDDING_DIM")
|
||||
|
||||
config = {
|
||||
"model": model,
|
||||
"dimension": int(dimension) if dimension is not None else None,
|
||||
}
|
||||
return config
|
||||
|
||||
|
||||
def init_settings():
|
||||
model = os.getenv("MODEL", "gpt-3.5-turbo")
|
||||
Settings.llm = OpenAI(model=model)
|
||||
Settings.chunk_size = 1024
|
||||
Settings.chunk_overlap = 20
|
||||
llm_configs = llm_config_from_env()
|
||||
embedding_configs = embedding_config_from_env()
|
||||
|
||||
Settings.llm = OpenAI(**llm_configs)
|
||||
Settings.embed_model = OpenAIEmbedding(**embedding_configs)
|
||||
Settings.chunk_size = int(os.getenv("CHUNK_SIZE", "1024"))
|
||||
Settings.chunk_overlap = int(os.getenv("CHUNK_OVERLAP", "20"))
|
||||
|
||||
@@ -33,4 +33,7 @@ app.include_router(chat_router, prefix="/api/chat")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app="main:app", host="0.0.0.0", reload=True)
|
||||
app_host = os.getenv("APP_HOST", "0.0.0.0")
|
||||
app_port = int(os.getenv("APP_PORT", "8000"))
|
||||
|
||||
uvicorn.run(app="main:app", host=app_host, port=app_port, reload=True)
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
webpack: (config) => {
|
||||
// See https://webpack.js.org/configuration/resolve/#resolvealias
|
||||
config.resolve.alias = {
|
||||
...config.resolve.alias,
|
||||
sharp$: false,
|
||||
"onnxruntime-node$": false,
|
||||
};
|
||||
return config;
|
||||
},
|
||||
experimental: {
|
||||
outputFileTracingIncludes: {
|
||||
"/*": ["./cache/**/*"],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = nextConfig;
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"experimental": {
|
||||
"outputFileTracingIncludes": {
|
||||
"/*": ["./cache/**/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
import fs from "fs";
|
||||
import webpack from "./webpack.config.mjs";
|
||||
|
||||
const nextConfig = JSON.parse(fs.readFileSync("./next.config.json", "utf-8"));
|
||||
nextConfig.webpack = webpack;
|
||||
|
||||
export default nextConfig;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user