Compare commits

...

154 Commits

Author SHA1 Message Date
github-actions[bot] 74fc725f37 Release 0.6.0 (#1199)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: marcusschiesser <marcusschiesser@users.noreply.github.com>
2024-09-13 16:07:16 +07:00
Marcus Schiesser a0a74aed60 fix: release openai package (#1200) 2024-09-13 16:01:00 +07:00
Marcus Schiesser 11feef8c82 Add workflows (#1188)
Co-authored-by: Thuc Pham <51660321+thucpn@users.noreply.github.com>
2024-09-13 15:46:02 +07:00
github-actions[bot] 9c5ff164ac Release 0.5.27 (#1195)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-12 13:47:11 -07:00
Alex Yang 7edeb1c2d7 feat: decouple openai from llamaindex module (#1194) 2024-09-12 13:36:08 -07:00
github-actions[bot] 8b95abdc85 Release 0.5.26 (#1193)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-12 11:38:07 -07:00
Alex Yang ffe0cd1ef1 chore: update changelog 2024-09-12 11:33:32 -07:00
Alex Yang 5d2111a19f feat: init support openai o1 model (#1192) 2024-09-12 11:31:05 -07:00
Alex Yang 68ac7fd57f ci: fix syntax (#1186) 2024-09-11 16:54:39 -07:00
Alex Yang 7320d96a36 fix: waku build (#1185) 2024-09-11 15:36:39 -07:00
Goran ee17fb475b feat: add PostgreSQL storage (#1180) 2024-09-11 12:31:04 -07:00
github-actions[bot] 28b877e31f Release 0.5.25 (#1182)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-11 12:08:39 -07:00
Alex Yang 4389b80a52 docs: update README.md (#1183) 2024-09-11 11:07:00 -07:00
Alex Yang d3bc663951 fix: vector store cleanup (#1175) 2024-09-11 10:20:55 -07:00
Kieran Simkin 4810364788 fix: handle RouterQueryEngine with string query (#1181) 2024-09-11 10:19:59 -07:00
github-actions[bot] 2dcad52dd9 Release 0.5.24 (#1178)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-10 23:48:51 -07:00
Alex Yang 0bf8d80b12 fix: llama cloud api build 2024-09-10 23:39:58 -07:00
github-actions[bot] e4bba02aec Release 0.5.23 (#1174)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-10 11:41:49 -07:00
Alex Yang 1caa0da657 chore: fix changeset 2024-09-10 11:34:07 -07:00
Alex Yang 711c814bb2 fix: patch python-format-js (#1173) 2024-09-10 09:49:36 -07:00
Alex Yang 5b832eb927 fix: strict type check (#1170) 2024-09-10 09:28:44 -07:00
Alex Yang 49988431f6 refactor: move settings.llm into core package (#1165) 2024-09-09 10:45:57 -07:00
Alex Yang 72d65dd51a docs: fix example (#1168) 2024-09-09 10:45:30 -07:00
Alex Yang 553bc55b19 refactor: move PromptHelper into core package (#1166) 2024-09-09 10:15:21 -07:00
Alex Yang fc6f69833c fix: example code (#1167) 2024-09-09 10:11:58 -07:00
github-actions[bot] c7fd06841f Release 0.5.22 (#1164)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-09 09:27:26 -07:00
Thuc Pham 4648da6849 fix: wrong tiktoken version caused NextJs CL template run fail (#1162) 2024-09-09 09:23:13 -07:00
Fabian Wimmer 0188cf3bb6 docs: fix typos, add API references (#1161) 2024-09-09 11:40:05 +07:00
Alex Yang e0b4f9c047 refactor: move constant into core module (#1158) 2024-09-06 20:29:08 -07:00
github-actions[bot] 4895bba96e Release 0.5.21 (#1140)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-06 15:26:14 -07:00
Alex Yang 76d1df817b chore: update tall-kangaroos-sleep.md 2024-09-06 15:11:10 -07:00
Ryan Lee 83d7f415e2 fix: database insertion for PGVectorStore (#1157) 2024-09-06 14:32:48 -07:00
Fabian Wimmer ae1149ffaf feat: add json streaming to JSONReader (#1119) 2024-09-06 11:22:21 -07:00
Alex Yang 0148354dbe refactor: prompt system (#1154) 2024-09-06 11:22:08 -07:00
Thuc Pham 11b3856334 feat: implement filters for MongoDBAtlasVectorSearch (#1142) 2024-09-05 14:11:31 +07:00
Philipp Serrer e8f229cd01 chore: remove logging from mongodb atlas vector store (#1145) 2024-09-03 18:01:52 -07:00
Alex Yang 75b70e5824 fix: remove Stream API polyfill (#1149) 2024-09-03 18:01:42 -07:00
Marcus Schiesser 1711f6d8fc fix: Export imageToDataUrl for using images in chat (#1146) 2024-09-03 10:56:30 +07:00
Alex Yang 20d16abdf4 chore: bump version (#1143) 2024-08-30 13:08:14 -07:00
Thuc Pham 2411c9fbd0 feat: Auto-create index for MongoDB vector store (if not exists) (#1139)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-08-30 14:24:20 +07:00
Phil Nash be3e280f2a Updates references to SimpleNodeParser to SentenceSplitter. (#1129) 2024-08-30 11:15:57 +07:00
github-actions[bot] 2afcbe6587 Release 0.5.20 (#1132)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-28 10:43:26 +07:00
Marcus Schiesser 22ff486fbe fix: Add tiktoken WASM to withLlamaIndex (#1134)
Co-authored-by: Thuc Pham <51660321+thucpn@users.noreply.github.com>
2024-08-28 10:39:14 +07:00
Thuc Pham eed0b0415d fix: use metadata mode LLM for generating context (#1133)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-08-23 22:56:18 +07:00
Sebastian van Gerwen d9d6c56ed5 pgvectorstore support new conditions and operations (#1131)
Co-authored-by: Sebastian van Gerwen <svangerwen@invertigro.com>
Co-authored-by: Marcus Schiesser <marcus.schiesser@googlemail.com>
2024-08-23 14:40:39 +07:00
github-actions[bot] f99a237093 Release 0.5.19 (#1128)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-19 14:04:47 +07:00
Thuc Pham fcbf18344c feat: implement llamacloud file service (#1125) 2024-08-19 14:01:41 +07:00
github-actions[bot] bf8cbeb6c5 Release 0.5.18 (#1124)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-19 12:53:28 +09:00
Alex Yang e27e7dd054 chore: bump natural to 8.0.1 (#1126) 2024-08-17 07:15:08 -07:00
Thuc Pham 8b66cf4341 feat: support organization id in llamacloud index (#1123)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-08-15 13:51:48 +07:00
github-actions[bot] 6f4549bdea Release 0.5.17 (#1117)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-12 17:45:29 +07:00
Thuc Pham c654398f75 feat: implement Weaviate Vector Store in TS (#1109) 2024-08-12 17:41:05 +07:00
github-actions[bot] 0664a99945 Release 0.5.16 (#1115)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-09 22:09:34 -07:00
Alex Yang 58abc5731b chore: update changeset 2024-08-09 22:06:43 -07:00
github-actions[bot] 7498b1e0f1 Release 0.5.15 (#1108)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-09 14:36:47 -07:00
Alex Yang 07a275fea5 chore: bump openai (#1113) 2024-08-09 12:56:30 -07:00
Alex Yang 1b6263e08d fix: export schema in top level (#1112) 2024-08-09 10:10:12 -07:00
Alex Yang 089f1d49c0 refactor: migrate reader type into core (#1111) 2024-08-09 09:53:50 -07:00
Thuc Pham 01c184c608 feat: add is_empty operator for filtering vector store (#1107) 2024-08-09 14:50:57 +07:00
github-actions[bot] 1752463ee6 Release 0.5.14 (#1103)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-07 17:03:00 -07:00
Peter Goldstein c825a2f743 Add gpt-4o-mini to Azure. Add 2024-06-01 API version for Azure (#1102) 2024-08-06 14:23:28 +07:00
github-actions[bot] ba058dc8d4 Release 0.5.13 (#1100)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-08-02 09:50:07 -07:00
Philipp Serrer 04b2f8e062 fix: metadata should not be included after sentence splitter (#1099) 2024-08-02 09:22:04 -07:00
Alex Yang 62b874e14f fix: enforce no-base-to-string (#1097) 2024-08-01 14:05:19 -07:00
github-actions[bot] 9c9e9b4e03 Release 0.5.12 (#1091)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-30 15:46:39 -07:00
Alex Yang e3c307ab55 chore: fix changeset 2024-07-30 15:32:24 -07:00
André Lago b1b2baa969 docs: fix minor typo (#1092) 2024-07-30 15:07:46 -07:00
Marcus Schiesser 0452af91cc fix: handling errors in splitBySentenceTokenizer (#1087)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-07-30 09:36:58 -07:00
Marcus Schiesser da5cfc42e5 fix: integrate with create-llama (#1088)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-07-30 08:19:32 -07:00
Alex Yang eb89223386 chore: bump bunchee@5.3.1 (#1090) 2024-07-30 08:19:01 -07:00
Alex Yang 93dc3a31b3 fix: lock hey-api version (#1089) 2024-07-30 08:00:05 -07:00
Fabian Wimmer 345300f110 feat: add split by page mode to LlamaParseReader (#924) 2024-07-29 16:16:46 +07:00
github-actions[bot] f322c5d202 Release 0.5.11 (#1082)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-26 21:26:11 -07:00
Parham Saidi 376d29a78f feat: meta3.1 405b tool calling support (#1080) 2024-07-26 19:53:24 -07:00
Parham Saidi 224d507ab5 fix: prevent anthropic tool calling getting mixed with conversation (#1078) 2024-07-26 09:55:22 -07:00
Alex Yang 1f680d731d chore: bump llamacloud api (#1081) 2024-07-26 09:53:50 -07:00
github-actions[bot] f0a1cc51b4 Release 0.5.10 (#1074)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-25 16:43:17 -07:00
Alex Yang fee3280799 chore: fix changelog 2024-07-25 11:21:16 -07:00
Alex Yang 54925bf1ae chore: fix changelog 2024-07-25 11:20:47 -07:00
Alex Yang 91d02a4fc0 feat: support transform component callable (#1072) 2024-07-25 11:19:57 -07:00
Erik 086b94038e feat: add DeepSeek LLM class and documentation (#1071) 2024-07-25 11:15:34 -07:00
Fabian Wimmer 5d5716b339 feat: add a reader for JSON data (#1063) 2024-07-25 09:40:54 -07:00
Fabian Wimmer fb6db454d4 feat: update/add pageSeparator params to LlamaParseReader (#1051) 2024-07-25 15:09:43 +07:00
Marcus Schiesser e4d4e0d024 docs: update CONTRIBUTING.md (#1073) 2024-07-25 00:59:45 -07:00
Diego Ferreiro Val 17724d961e feat: add support for buffer on loadJSON API on LlamaParseReader (#1069)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-07-25 14:44:46 +07:00
github-actions[bot] 6776910c93 Release 0.5.9 (#1070)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-24 12:04:51 -07:00
Alex Yang 15962b36f0 feat: node parser refactor (#1065) 2024-07-24 10:46:00 -07:00
Parham Saidi 3d9a802734 feat: bedrock meta llama 3.1 8b, 70b and 405B (#1068) 2024-07-24 10:45:49 -07:00
github-actions[bot] 9cd8f8b0cf Release 0.5.8 (#1067)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-24 01:43:09 -07:00
Alex Yang b44330cbc6 chore: fix changelog 2024-07-24 01:28:40 -07:00
Niels Swimberghe 3d5ba0873c fix: update user agent in AssemblyAI (#1039)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-07-24 00:50:35 -07:00
Thuc Pham d917cdc3fa feat: add azure interpreter tool to tool factory (#1064) 2024-07-23 16:04:36 +07:00
github-actions[bot] b370edf329 Release 0.5.7 (#1062)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-22 10:07:44 -07:00
Marcus Schiesser ec59acd329 fix: bundling issue with pnpm (#1060)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-07-22 09:37:13 -07:00
github-actions[bot] c69e740c56 Release 0.5.6 (#1048)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-18 15:20:19 -07:00
Alex Yang 6cf6ae631c feat: abstract query type (#1052) 2024-07-18 13:27:02 -07:00
Alex Yang 2562244fb6 feat: add gpt4o-mini (#1057) 2024-07-18 12:50:51 -07:00
Thuc Pham a2691ee163 fix: always return false when key not exist in metadata (#1056) 2024-07-18 22:52:00 +07:00
Marcus Schiesser ab700ea546 fix: Add missing authentication to LlamaCloudIndex.fromDocuments (#1055) 2024-07-18 16:32:07 +07:00
Marcus Schiesser e775afc3f2 docs: clarify similarityTopK usage (#1053) 2024-07-18 16:24:49 +07:00
Alex Yang 92f07824a7 feat: use query bundle (#702) 2024-07-17 20:17:06 -07:00
Igor Soares b7cfe5bce6 fix: passing max_token option to replicate's api call (#1050)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-07-17 12:00:30 -07:00
Chris Paganon 3ccfb28352 docs: fix deprecated similarityTopK for retriever (#1049) 2024-07-17 11:59:28 -07:00
Thuc Pham 325aa51e51 feat: implement Jina embedding through Jina api (#995)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-07-17 20:57:14 +07:00
Marcus Schiesser d1d9bd6e41 docs: add metadata filter operators (#1047) 2024-07-17 17:00:37 +07:00
github-actions[bot] 9a71382243 Release 0.5.5 (#1046)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-17 16:26:38 +07:00
Thuc Pham b974eea341 feat: add MetadataFilter for SimpleVectorStore and Milvus (#1030)
Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
2024-07-17 16:21:21 +07:00
github-actions[bot] e82632f83d Release 0.5.4 (#1043)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-16 14:53:20 -07:00
Fabian Wimmer 1a65ead849 feat: add vendorMultiModal params to LlamaParseReader (#1042) 2024-07-16 14:20:34 -07:00
Alex Yang 50b7d1b7bb refactor: put embedding into core (#1041) 2024-07-16 10:49:03 -07:00
github-actions[bot] 09beb72f5b Release 0.5.3 (#1038)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-16 10:25:27 -07:00
Fabian Wimmer 9bbbc67c8e feat: add a reader for Discord messages (#1040) 2024-07-16 10:19:48 -07:00
Brian Peiris b3681bf681 fix: DataCloneError when using FunctionTool (#1037) 2024-07-14 15:24:49 -07:00
Alex Yang b548b1443b chore: bump version (#1032) 2024-07-12 15:14:27 -07:00
github-actions[bot] 0e980d962d Release 0.5.2 (#1035)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-12 11:44:32 -07:00
Alex Yang 3ed6acc6a6 chore: bump cloud api (#1036) 2024-07-12 11:21:37 -07:00
Parham Saidi 56746c240f fix: bedrock handle empty content and added max tokens export (#1034) 2024-07-12 09:47:49 -07:00
Alex Yang 5c1c2c7f5b ci: only commit lock file (#1031) 2024-07-10 10:17:35 -07:00
github-actions[bot] a699086f46 Release 0.5.1 (#1028)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-09 15:36:20 -07:00
Alex Yang 454c204112 chore: bump version (#1029) 2024-07-09 13:42:09 -07:00
Julius Lipp 277468160d feat: add mixedbread ai integration (#953) 2024-07-09 09:36:43 -07:00
Ranjan Mangla a0f424e592 fix: corrected the regex in the ReactAgent (#1022)
Signed-off-by: ranjanmangla1 <ranjanmangla1@gmail.com>
2024-07-09 08:55:38 -07:00
github-actions[bot] 3ae832ca28 Release 0.5.0 (#1024)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: himself65 <himself65@users.noreply.github.com>
2024-07-08 17:16:46 -07:00
Alex Yang 16ef5dd631 feat: simplify callback manager (#1027) 2024-07-08 16:44:54 -07:00
Alex Yang c4bd0a5215 refactor: move llm & callback manager to core module (#1026) 2024-07-08 15:48:59 -07:00
Alex Yang f5c8ca7dfb chore: use bunchee bundler for all (#1025) 2024-07-08 09:45:55 -07:00
Sacha Bron 36ddec44af fix: typo in custom page separator parameter for LlamaParse (#1023) 2024-07-08 09:27:51 -07:00
github-actions[bot] c147d8a271 Release 0.4.14 (#1021)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-05 15:26:31 -07:00
Alex Yang 1c444d58b6 feat(cloud): update openapi.json (#1020) 2024-07-05 15:01:22 -07:00
github-actions[bot] 1f910f7566 Release 0.4.13 (#1016)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-05 11:44:37 -07:00
Thuc Pham 99826cff43 fix: missing dispatch retrieve event on llamacloud retriever (#1018) 2024-07-05 20:43:26 +07:00
Fabian Wimmer e8f8bea969 feat: add boundingBox and targetPages to LlamaParseReader (#1017) 2024-07-05 14:32:26 +07:00
Fabian Wimmer 304484b77a feat: add ignoreErrors flag to LlamaParse (#959)
Co-authored-by: Marcus Schiesser <marcus.schiesser@googlemail.com>
2024-07-04 20:51:05 +07:00
abgita 29fed77d58 Fixed a typo in the retriever description (#1009) 2024-07-04 20:15:20 +07:00
Alex Yang db070588c8 ci: fix setup pnpm (#1014) 2024-07-03 12:11:48 -07:00
github-actions[bot] 76deca7fea Release 0.4.12 (#1013)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-03 10:24:22 -07:00
Alex Yang f326ab86d2 chore: bump version 2024-07-03 10:20:46 -07:00
Cássio de Freitas e Silva ca8d9709e0 feat: add support for Meta LLMs in AWS Bedrock (#960) 2024-07-03 01:27:58 -07:00
github-actions[bot] e0af059221 Release 0.4.11 (#1008)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-02 15:07:03 -07:00
Alex Yang 8bf5b4acfd fix: llama parse input spreadsheet (#1007) 2024-07-02 14:48:51 -07:00
Alex Yang 93a003baa0 ci: pre release (#1005) 2024-07-02 00:40:45 -07:00
github-actions[bot] 5d9b0bd3f0 Release 0.4.10 (#1003)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-01 23:59:52 -07:00
Alex Yang 9a5525e1b3 refactor(core): migrate llms type (#1002) 2024-07-01 20:13:35 -07:00
Peron 7dce3d28d3 fix: disable External Filters for Gemini (#994)
Co-authored-by: Alex Yang <himself65@outlook.com>
2024-07-01 18:28:22 -07:00
github-actions[bot] d4c1482c1c Release 0.4.9 (#1001)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-01 17:20:47 -07:00
Alex Yang 3a96a483a6 fix: anthropic image input (#999) 2024-07-01 16:03:30 -07:00
Alex Yang 7467fce2d4 docs: remove cloudflare worker section (#1000) 2024-07-01 16:01:55 -07:00
github-actions[bot] 06af08cac4 Release 0.4.8 (#998)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-01 15:07:50 -07:00
Alex Yang 83ebdfb1c5 fix: next.js binding (#997) 2024-07-01 14:52:57 -07:00
github-actions[bot] 835b1ac000 Release 0.4.7 (#986)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-06-28 22:58:14 -07:00
Alex Yang f10b41dbc1 chore: fix release files (#991) 2024-06-28 13:36:55 -07:00
Wassim Chegham 41fe871e2f feat: add support for azure dynamic session tool (#942)
Co-authored-by: Marcus Schiesser <marcus.schiesser@googlemail.com>
2024-06-27 13:18:05 -07:00
Alex Yang 321c39ddc7 fix: generate api as class (#988) 2024-06-27 09:58:00 -07:00
Alex Yang f7f1af0139 fix: llamacloud sdk edge case (#985) 2024-06-26 23:10:04 -07:00
458 changed files with 28870 additions and 13471 deletions
+6 -1
View File
@@ -31,7 +31,12 @@ module.exports = {
"@typescript-eslint/ban-types": "off",
"no-array-constructor": "off",
"@typescript-eslint/no-array-constructor": "off",
"@typescript-eslint/no-base-to-string": "off",
"@typescript-eslint/no-base-to-string": [
"error",
{
ignoredTypeNames: ["Error", "RegExp", "URL", "URLSearchParams"],
},
],
"@typescript-eslint/no-duplicate-enum-values": "off",
"@typescript-eslint/no-duplicate-type-constituents": "off",
"@typescript-eslint/no-explicit-any": "off",
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
+28
View File
@@ -0,0 +1,28 @@
name: Publish Preview
on: [pull_request]
jobs:
pre_release:
name: Pre Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Pre Release
run: pnpx pkg-pr-new publish ./packages/*
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
- name: Checkout Repo
uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
+2 -1
View File
@@ -15,7 +15,7 @@ jobs:
- name: Checkout Repo
uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
@@ -67,3 +67,4 @@ jobs:
with:
commit_message: "chore: update lock file"
branch: changeset-release/main
file_pattern: "pnpm-lock.yaml"
+23 -9
View File
@@ -12,6 +12,10 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
POSTGRES_USER: runneradmin
POSTGRES_HOST_AUTH_METHOD: trust
jobs:
e2e:
strategy:
@@ -22,9 +26,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: ankane/setup-postgres@v1
with:
database: llamaindex_node_test
dev-files: true
- run: |
cd /tmp
git clone --branch v0.7.0 https://github.com/pgvector/pgvector.git
cd pgvector
make
sudo make install
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
@@ -42,10 +54,9 @@ jobs:
node-version: [18.x, 20.x, 22.x]
name: Test on Node.js ${{ matrix.node-version }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
@@ -60,7 +71,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
@@ -92,12 +103,12 @@ jobs:
- nextjs-agent
- nextjs-edge-runtime
- nextjs-node-runtime
# - waku-query-engine
- waku-query-engine
runs-on: ubuntu-latest
name: Build LlamaIndex Example (${{ matrix.packages }})
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
@@ -116,7 +127,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
@@ -131,6 +142,9 @@ jobs:
- name: Pack @llamaindex/cloud
run: pnpm pack --pack-destination ${{ runner.temp }}
working-directory: packages/cloud
- name: Pack @llamaindex/openai
run: pnpm pack --pack-destination ${{ runner.temp }}
working-directory: packages/llm/openai
- name: Pack @llamaindex/core
run: pnpm pack --pack-destination ${{ runner.temp }}
working-directory: packages/core
+7 -7
View File
@@ -4,11 +4,11 @@
This is a monorepo built with Turborepo
Right now there are two packages of importance:
Right now, for first-time contributors, these three packages are of the highest importance:
packages/llamaindex which is the main NPM library llamaindex
examples is where the demo code lives
- `packages/llamaindex` which is the main NPM library `llamaindex`
- `examples` is where the demo code lives
- `apps/docs` is where the code for the documentation of https://ts.llamaindex.ai/ is located
### Turborepo docs
@@ -43,11 +43,11 @@ pnpm run test
To write new test cases write them in [packages/llamaindex/tests](/packages/llamaindex/tests)
We use Jest https://jestjs.io/ to write our test cases. Jest comes with a bunch of built in assertions using the expect function: https://jestjs.io/docs/expect
We use Vitest https://vitest.dev to write our test cases. Vitest comes with a bunch of built-in assertions using the expect function: https://vitest.dev/api/expect.html#expect
### Demo applications
There is an existing ["example"](/examples/README.md) demos folder with mainly NodeJS scripts. Feel free to add additional demos to that folder. If you would like to try out your changes in the core package with a new demo, you need to run the build command in the README.
There is an existing ["example"](/examples/README.md) demos folder with mainly NodeJS scripts. Feel free to add additional demos to that folder. If you would like to try out your changes in the `llamaindex` package with a new demo, you need to run the build command in the README.
You can create new demo applications in the apps folder. Just run pnpm init in the folder after you create it to create its own package.json
@@ -81,7 +81,7 @@ Any changes you make should be reflected in the browser. If you need to regenera
## Changeset
We use [changesets](https://github.com/changesets/changesets) for managing versions and changelogs. To create a new changeset, run:
We use [changesets](https://github.com/changesets/changesets) for managing versions and changelogs. To create a new changeset, run in the root folder:
```
pnpm changeset
+46 -30
View File
@@ -36,9 +36,44 @@ For now, browser support is limited due to the lack of support for [AsyncLocalSt
npm install llamaindex
pnpm install llamaindex
yarn add llamaindex
jsr install @llamaindex/core
```
### Setup TypeScript
```json5
{
compilerOptions: {
// ⬇️ add this line to your tsconfig.json
moduleResolution: "bundler", // or "node16"
},
}
```
<details>
<summary>Why?</summary>
We are shipping both ESM and CJS module, and compatible with Vercel Edge, Cloudflare Workers, and other serverless platforms.
So we are using [conditional exports](https://nodejs.org/api/packages.html#conditional-exports) to support all environments.
This is a kind of modern way of shipping packages, but might cause TypeScript type check to fail because of legacy module resolution.
Imaging you put output file into `/dist/openai.js` but you are importing `llamaindex/openai` in your code, and set `package.json` like this:
```json
{
"exports": {
"./openai": "./dist/openai.js"
}
}
```
In old module resolution, TypeScript will not be able to find the module because it is not follow the file structure, even you run `node index.js` successfully. (on Node.js >=16)
See more about [moduleResolution](https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution) or
[TypeScript 5.0 blog](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#--moduleresolution-bundler7).
</details>
### Node.js
```ts
@@ -76,7 +111,7 @@ main();
node --import tsx ./main.ts
```
### Next.js
### React Server Component (Next.js, Waku, Redwood.JS...)
First, you will need to add a llamaindex plugin to your Next.js project.
@@ -154,36 +189,17 @@ export async function chatWithAgent(
}
```
### Cloudflare Workers
### Vite
We have some wasm dependencies for better performance. You can use `vite-plugin-wasm` to load them.
```ts
// src/index.ts
import wasm from "vite-plugin-wasm";
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext,
): Promise<Response> {
const { setEnvs } = await import("@llamaindex/env");
// set environment variables so that the OpenAIAgent can use them
setEnvs(env);
const { OpenAIAgent } = await import("llamaindex");
const agent = new OpenAIAgent({
tools: [],
});
const responseStream = await agent.chat({
stream: true,
message: "Hello? What is the weather today?",
});
const textEncoder = new TextEncoder();
const response = responseStream.pipeThrough(
new TransformStream({
transform: (chunk, controller) => {
controller.enqueue(textEncoder.encode(chunk.response.delta));
},
}),
);
return new Response(response);
plugins: [wasm()],
ssr: {
external: ["tiktoken"],
},
};
```
@@ -198,7 +214,7 @@ Check out our NextJS playground at https://llama-playground.vercel.app/. The sou
- [Node](/packages/llamaindex/src/Node.ts): The basic data building block. Most commonly, these are parts of the document split into manageable pieces that are small enough to be fed into an embedding model and LLM.
- [Embedding](/packages/llamaindex/src/embeddings/OpenAIEmbedding.ts): Embeddings are sets of floating point numbers which represent the data in a Node. By comparing the similarity of embeddings, we can derive an understanding of the similarity of two pieces of data. One use case is to compare the embedding of a question with the embeddings of our Nodes to see which Nodes may contain the data needed to answer that quesiton. Because the default service context is OpenAI, the default embedding is `OpenAIEmbedding`. If using different models, say through Ollama, use this [Embedding](/packages/llamaindex/src/embeddings/OllamaEmbedding.ts) (see all [here](/packages/llamaindex/src/embeddings)).
- [Embedding](/packages/llamaindex/src/embeddings/OpenAIEmbedding.ts): Embeddings are sets of floating point numbers which represent the data in a Node. By comparing the similarity of embeddings, we can derive an understanding of the similarity of two pieces of data. One use case is to compare the embedding of a question with the embeddings of our Nodes to see which Nodes may contain the data needed to answer that question. Because the default service context is OpenAI, the default embedding is `OpenAIEmbedding`. If using different models, say through Ollama, use this [Embedding](/packages/llamaindex/src/embeddings/OllamaEmbedding.ts) (see all [here](/packages/llamaindex/src/embeddings)).
- [Indices](/packages/llamaindex/src/indices/): Indices store the Nodes and the embeddings of those nodes. QueryEngines retrieve Nodes from these Indices using embedding similarity.
+6
View File
@@ -0,0 +1,6 @@
---
"llamaindex": minor
"docs": minor
---
Add deepseek llm class
+289
View File
@@ -1,5 +1,294 @@
# docs
## 0.0.69
### Patch Changes
- Updated dependencies [11feef8]
- llamaindex@0.6.0
- @llamaindex/examples@0.0.8
## 0.0.68
### Patch Changes
- Updated dependencies [7edeb1c]
- llamaindex@0.5.27
## 0.0.67
### Patch Changes
- Updated dependencies [ffe0cd1]
- Updated dependencies [ffe0cd1]
- llamaindex@0.5.26
## 0.0.66
### Patch Changes
- Updated dependencies [4810364]
- Updated dependencies [d3bc663]
- llamaindex@0.5.25
## 0.0.65
### Patch Changes
- llamaindex@0.5.24
## 0.0.64
### Patch Changes
- llamaindex@0.5.23
## 0.0.63
### Patch Changes
- Updated dependencies [4648da6]
- llamaindex@0.5.22
## 0.0.62
### Patch Changes
- Updated dependencies [ae1149f]
- Updated dependencies [2411c9f]
- Updated dependencies [e8f229c]
- Updated dependencies [11b3856]
- Updated dependencies [83d7f41]
- Updated dependencies [0148354]
- Updated dependencies [1711f6d]
- llamaindex@0.5.21
## 0.0.61
### Patch Changes
- Updated dependencies [d9d6c56]
- Updated dependencies [22ff486]
- Updated dependencies [eed0b04]
- llamaindex@0.5.20
## 0.0.60
### Patch Changes
- Updated dependencies [fcbf183]
- llamaindex@0.5.19
## 0.0.59
### Patch Changes
- Updated dependencies [8b66cf4]
- llamaindex@0.5.18
## 0.0.58
### Patch Changes
- Updated dependencies [c654398]
- llamaindex@0.5.17
## 0.0.57
### Patch Changes
- Updated dependencies [58abc57]
- llamaindex@0.5.16
## 0.0.56
### Patch Changes
- Updated dependencies [01c184c]
- Updated dependencies [07a275f]
- llamaindex@0.5.15
## 0.0.55
### Patch Changes
- Updated dependencies [c825a2f]
- llamaindex@0.5.14
## 0.0.54
### Patch Changes
- llamaindex@0.5.13
## 0.0.53
### Patch Changes
- Updated dependencies [345300f]
- Updated dependencies [da5cfc4]
- Updated dependencies [da5cfc4]
- llamaindex@0.5.12
## 0.0.52
### Patch Changes
- 376d29a: feat: added tool calling and agent support for llama3.1 504B
- llamaindex@0.5.11
## 0.0.51
### Patch Changes
- 086b940: feat: add DeepSeek LLM
- 5d5716b: feat: add a reader for JSON data
- Updated dependencies [086b940]
- Updated dependencies [5d5716b]
- Updated dependencies [91d02a4]
- Updated dependencies [fb6db45]
- llamaindex@0.5.10
## 0.0.50
### Patch Changes
- Updated dependencies [15962b3]
- llamaindex@0.5.9
## 0.0.49
### Patch Changes
- Updated dependencies [3d5ba08]
- Updated dependencies [d917cdc]
- llamaindex@0.5.8
## 0.0.48
### Patch Changes
- Updated dependencies [ec59acd]
- llamaindex@0.5.7
## 0.0.47
### Patch Changes
- Updated dependencies [2562244]
- Updated dependencies [325aa51]
- Updated dependencies [ab700ea]
- Updated dependencies [92f0782]
- Updated dependencies [6cf6ae6]
- Updated dependencies [b7cfe5b]
- llamaindex@0.5.6
## 0.0.46
### Patch Changes
- Updated dependencies [b974eea]
- llamaindex@0.5.5
## 0.0.45
### Patch Changes
- Updated dependencies [1a65ead]
- llamaindex@0.5.4
## 0.0.44
### Patch Changes
- Updated dependencies [9bbbc67]
- Updated dependencies [b3681bf]
- llamaindex@0.5.3
## 0.0.43
### Patch Changes
- llamaindex@0.5.2
## 0.0.42
### Patch Changes
- 2774681: Add mixedbread's embeddings and reranking API
- Updated dependencies [2774681]
- Updated dependencies [a0f424e]
- llamaindex@0.5.1
## 0.0.41
### Patch Changes
- 36ddec4: fix: typo in custom page separator parameter for LlamaParse
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
- @llamaindex/examples@0.0.7
## 0.0.40
### Patch Changes
- llamaindex@0.4.14
## 0.0.39
### Patch Changes
- Updated dependencies [e8f8bea]
- Updated dependencies [304484b]
- llamaindex@0.4.13
## 0.0.38
### Patch Changes
- Updated dependencies [f326ab8]
- llamaindex@0.4.12
## 0.0.37
### Patch Changes
- Updated dependencies [8bf5b4a]
- llamaindex@0.4.11
## 0.0.36
### Patch Changes
- Updated dependencies [7dce3d2]
- llamaindex@0.4.10
## 0.0.35
### Patch Changes
- Updated dependencies [3a96a48]
- llamaindex@0.4.9
## 0.0.34
### Patch Changes
- Updated dependencies [83ebdfb]
- llamaindex@0.4.8
## 0.0.33
### Patch Changes
- Updated dependencies [41fe871]
- Updated dependencies [321c39d]
- Updated dependencies [f7f1af0]
- llamaindex@0.4.7
## 0.0.32
### Patch Changes
+1 -1
View File
@@ -62,7 +62,7 @@ These building blocks can be customized to reflect ranking preferences, as well
[**Retrievers**](../modules/retriever.md):
A retriever defines how to efficiently retrieve relevant context from a knowledge base (i.e. index) when given a query.
The specific retrieval logic differs for difference indices, the most popular being dense retrieval against a vector index.
The specific retrieval logic differs for different indices, the most popular being dense retrieval against a vector index.
[**Response Synthesizers**](../modules/response_synthesizer.md):
A response synthesizer generates a response from an LLM, using a user query and a given set of retrieved text chunks.
+10 -3
View File
@@ -6,10 +6,17 @@ sidebar_position: 2
We support Node.JS versions 18, 20 and 22, with experimental support for Deno, Bun and Vercel Edge functions.
## NextJS App Router
## NextJS
If you're using NextJS App Router route handlers/serverless functions, you'll need to use the NodeJS mode:
If you're using NextJS you'll need to add `withLlamaIndex` to your `next.config.js` file. This will add the necessary configuration for included 3rd-party libraries to your build:
```js
export const runtime = "nodejs"; // default
// next.config.js
const withLlamaIndex = require("llamaindex/next");
module.exports = withLlamaIndex({
// your next.js config
});
```
For details, check the latest [withLlamaIndex](https://github.com/run-llama/LlamaIndexTS/blob/main/packages/llamaindex/src/next.ts) implementation.
@@ -50,10 +50,10 @@ We want to see what our agent is up to, so we're going to hook into some events
```javascript
Settings.callbackManager.on("llm-tool-call", (event) => {
console.log(event.detail.payload);
console.log(event.detail);
});
Settings.callbackManager.on("llm-tool-result", (event) => {
console.log(event.detail.payload);
console.log(event.detail);
});
```
+1 -1
View File
@@ -21,7 +21,7 @@ LlamaIndex.TS handles several major use cases:
- **Structured Data Extraction**: turning complex, unstructured and semi-structured data into uniform, programmatically accessible formats.
- **Retrieval-Augmented Generation (RAG)**: answering queries across your internal data by providing LLMs with up-to-date, semantically relevant context including Question and Answer systems and chat bots.
- **Autonomous Agents**: building software that is capable of intelligently selecting and using tools to accomplish tasks in an interative, unsupervised manner.
- **Autonomous Agents**: building software that is capable of intelligently selecting and using tools to accomplish tasks in an interactive, unsupervised manner.
## 👨‍👩‍👧‍👦 Who is LlamaIndex for?
+1
View File
@@ -15,6 +15,7 @@ LlamaIndex.TS comes with a few built-in agents, but you can also create your own
- Anthropic Agent both via Anthropic and Bedrock (in `@llamaIndex/community`)
- Gemini Agent
- ReACT Agent
- Meta3.1 504B via Bedrock (in `@llamaIndex/community`)
## Examples
+1
View File
@@ -27,3 +27,4 @@ for await (const chunk of stream) {
- [ContextChatEngine](../api/classes/ContextChatEngine.md)
- [CondenseQuestionChatEngine](../api/classes/ContextChatEngine.md)
- [SimpleChatEngine](../api/classes/SimpleChatEngine.md)
+1
View File
@@ -21,3 +21,4 @@ const index = await VectorStoreIndex.fromDocuments([document]);
- [SummaryIndex](../api/classes/SummaryIndex.md)
- [VectorStoreIndex](../api/classes/VectorStoreIndex.md)
- [KeywordTableIndex](../api/classes/KeywordTableIndex.md)
@@ -0,0 +1,34 @@
import CodeBlock from "@theme/CodeBlock";
import CodeSource from "!raw-loader!../../../../../examples/readers/src/discord";
# DiscordReader
DiscordReader is a simple data loader that reads all messages in a given Discord channel and returns them as Document objects.
It uses the [@discordjs/rest](https://github.com/discordjs/discord.js/tree/main/packages/rest) library to fetch the messages.
## Usage
First step is to create a Discord Application and generating a bot token [here](https://discord.com/developers/applications).
In your Discord Application, go to the `OAuth2` tab and generate an invite URL by selecting `bot` and click `Read Messages/View Channels` as wells as `Read Message History`.
This will invite the bot with the necessary permissions to read messages.
Copy the URL in your browser and select the server you want your bot to join.
<CodeBlock language="ts">{CodeSource}</CodeBlock>
### Params
#### DiscordReader()
- `discordToken?`: The Discord bot token.
- `requestHandler?`: Optionally provide a custom request function for edge environments, e.g. `fetch`. See discord.js for more info.
#### DiscordReader.loadData
- `channelIDs`: The ID(s) of discord channels as an array of strings.
- `limit?`: Optionally limit the number of messages to read
- `additionalInfo?`: An optional flag to include embedded messages and attachment urls in the document.
- `oldestFirst?`: An optional flag to return the oldest messages first.
## API Reference
- [DiscordReader](../../api/classes/DiscordReader.md)
@@ -16,7 +16,15 @@ It is a simple reader that reads all files from a directory and its subdirectori
<CodeBlock language="ts">{CodeSource}</CodeBlock>
Currently, it supports reading `.txt`, `.pdf`, `.csv`, `.md`, `.docx`, `.htm`, `.html`, `.jpg`, `.jpeg`, `.png` and `.gif` files, but support for other file types is planned.
Currently, the following readers are mapped to specific file types:
- [TextFileReader](../../api/classes/TextFileReader.md): `.txt`
- [PDFReader](../../api/classes/PDFReader.md): `.pdf`
- [PapaCSVReader](../../api/classes/PapaCSVReader.md): `.csv`
- [MarkdownReader](../../api/classes/MarkdownReader.md): `.md`
- [DocxReader](../../api/classes/DocxReader.md): `.docx`
- [HTMLReader](../../api/classes/HTMLReader.md): `.htm`, `.html`
- [ImageReader](../../api/classes/ImageReader.md): `.jpg`, `.jpeg`, `.png`, `.gif`
You can modify the reader three different ways:
+149
View File
@@ -0,0 +1,149 @@
# JSONReader
A simple JSON data loader with various options.
Either parses the entire string, cleaning it and treat each line as an embedding or performs a recursive depth-first traversal yielding JSON paths.
Supports streaming of large JSON data using [@discoveryjs/json-ext](https://github.com/discoveryjs/json-ext)
## Usage
```ts
import { JSONReader } from "llamaindex";
const file = "../../PATH/TO/FILE";
const content = new TextEncoder().encode("JSON_CONTENT");
const reader = new JSONReader({ levelsBack: 0, collapseLength: 100 });
const docsFromFile = reader.loadData(file);
const docsFromContent = reader.loadDataAsContent(content);
```
### Options
Basic:
- `streamingThreshold?`: The threshold for using streaming mode in MB of the JSON Data. CEstimates characters by calculating bytes: `(streamingThreshold * 1024 * 1024) / 2` and comparing against `.length` of the JSON string. Set `undefined` to disable streaming or `0` to always use streaming. Default is `50` MB.
- `ensureAscii?`: Wether to ensure only ASCII characters be present in the output by converting non-ASCII characters to their unicode escape sequence. Default is `false`.
- `isJsonLines?`: Wether the JSON is in JSON Lines format. If true, will split into lines, remove empty one and parse each line as JSON. Note: Uses a custom streaming parser, most likely less robust than json-ext. Default is `false`
- `cleanJson?`: Whether to clean the JSON by filtering out structural characters (`{}, [], and ,`). If set to false, it will just parse the JSON, not removing structural characters. Default is `true`.
- `logger?`: A placeholder for a custom logger function.
Depth-First-Traversal:
- `levelsBack?`: Specifies how many levels up the JSON structure to include in the output. `cleanJson` will be ignored. If set to 0, all levels are included. If undefined, parses the entire JSON, treat each line as an embedding and create a document per top-level array. Default is `undefined`
- `collapseLength?`: The maximum length of JSON string representation to be collapsed into a single line. Only applicable when `levelsBack` is set. Default is `undefined`
#### Examples
<!-- prettier-ignore-start -->
Input:
```json
{"a": {"1": {"key1": "value1"}, "2": {"key2": "value2"}}, "b": {"3": {"k3": "v3"}, "4": {"k4": "v4"}}}
```
Default options:
`LevelsBack` = `undefined` & `cleanJson` = `true`
Output:
```json
"a": {
"1": {
"key1": "value1"
"2": {
"key2": "value2"
"b": {
"3": {
"k3": "v3"
"4": {
"k4": "v4"
```
Depth-First Traversal all levels:
`levelsBack` = `0`
Output:
```json
a 1 key1 value1
a 2 key2 value2
b 3 k3 v3
b 4 k4 v4
```
Depth-First Traversal and Collapse:
`levelsBack` = `0` & `collapseLength` = `35`
Output:
```json
a 1 {"key1":"value1"}
a 2 {"key2":"value2"}
b {"3":{"k3":"v3"},"4":{"k4":"v4"}}
```
Depth-First Traversal limited levels:
`levelsBack` = `2`
Output:
```json
1 key1 value1
2 key2 value2
3 k3 v3
4 k4 v4
```
Uncleaned JSON:
`levelsBack` = `undefined` & `cleanJson` = `false`
Output:
```json
{"a":{"1":{"key1":"value1"},"2":{"key2":"value2"}},"b":{"3":{"k3":"v3"},"4":{"k4":"v4"}}}
```
ASCII-Conversion:
Input:
```json
{ "message": "こんにちは世界" }
```
Output:
```json
"message": "\u3053\u3093\u306b\u3061\u306f\u4e16\u754c"
```
JSON Lines Format:
Input:
```json
{"tweet": "Hello world"}\n{"tweet": "こんにちは世界"}
```
Output:
```json
"tweet": "Hello world"
"tweet": "こんにちは世界"
```
<!-- prettier-ignore-end -->
## API Reference
- [JSONReader](../../api/classes/JSONReader.md)
@@ -27,23 +27,31 @@ They can be divided into two groups.
- `apiKey` is required. Can be set as an environment variable `LLAMA_CLOUD_API_KEY`
- `checkInterval` is the interval in seconds to check if the parsing is done. Default is `1`.
- `maxTimeout` is the maximum timout to wait for parsing to finish. Default is `2000`
- `maxTimeout` is the maximum timeout to wait for parsing to finish. Default is `2000`
- `verbose` shows progress of the parsing. Default is `true`
- `ignoreErrors` set to false to get errors while parsing. Default is `true` and returns an empty array on error.
#### Advanced params:
- `resultType` can be set to `markdown`, `text` or `json`. Defaults to `text`. More information about `json` mode on the next pages.
- `language` primarly helps with OCR recognition. Defaults to `en`. Click [here](../../../api/type-aliases/Language.md) for a list of supported languages.
- `language` primarily helps with OCR recognition. Defaults to `en`. Click [here](../../../api/type-aliases/Language.md) for a list of supported languages.
- `parsingInstructions?` Optional. Can help with complicated document structures. See this [LlamaIndex Blog Post](https://www.llamaindex.ai/blog/launching-the-first-genai-native-document-parsing-platform) for an example.
- `skipDiagonalText?` Optional. Set to true to ignore diagonal text. (Text that is not rotated 0, 90, 180 or 270 degrees)
- `invalidateCache?` Optional. Set to true to ignore the LlamaCloud cache. All document are kept in cache for 48hours after the job was completed to avoid processing the same document twice. Can be useful for testing when trying to re-parse the same document with, e.g. different `parsingInstructions`.
- `doNotCache?` Optional. Set to true to not cache the document.
- `fastMode?` Optional. Set to true to use the fast mode. This mode will skip OCR of images, and table/heading reconstruction. Note: Non-compatible with `gpt4oMode`.
- `doNotUnrollColumns?` Optional. Set to true to keep the text according to document layout. Reduce reconstruction accuracy, and LLM's/embedings performances in most cases.
- `pageSeperator?` Optional. The page seperator to use. Defaults is `\\n---\\n`.
- `gpt4oMode` set to true to use GPT-4o to extract content. Default is `false`.
- `gpt4oApiKey?` Optional. Set the GPT-4o API key. Lowers the cost of parsing by using your own API key. Your OpenAI account will be charged. Can also be set in the environment variable `LLAMA_CLOUD_GPT4O_API_KEY`.
- `doNotUnrollColumns?` Optional. Set to true to keep the text according to document layout. Reduce reconstruction accuracy, and LLMs/embeddings performances in most cases.
- `pageSeparator?` Optional. A templated page separator to use to split the text. If the results contain `{page_number}` (e.g. JSON mode), it will be replaced by the next page number. If not set the default separator `\\n---\\n` will be used.
- `pagePrefix?` Optional. A templated prefix to add to the beginning of each page. If the results contain `{page_number}`, it will be replaced by the page number.
- `pageSuffix?` Optional. A templated suffix to add to the end of each page. If the results contain `{page_number}`, it will be replaced by the page number.
- `gpt4oMode` Deprecated. Use vendorMultimodal params. Set to true to use GPT-4o to extract content. Default is `false`.
- `gpt4oApiKey?` Deprecated. Use vendorMultimodal params. Optional. Set the GPT-4o API key. Lowers the cost of parsing by using your own API key. Your OpenAI account will be charged. Can also be set in the environment variable `LLAMA_CLOUD_GPT4O_API_KEY`.
- `boundingBox?` Optional. Specify an area of the document to parse. Expects the bounding box margins as a string in clockwise order, e.g. `boundingBox = "0.1,0,0,0"` to not parse the top 10% of the document.
- `targetPages?` Optional. Specify which pages to parse by specifying them as a comma-separated list. First page is `0`.
- `splitByPage` Wether to split the results, creating one document per page. Uses the set `pageSeparator` or `\n---\n` as fallback. Default is true.
- `useVendorMultimodalModel` set to true to use a multimodal model. Default is `false`.
- `vendorMultimodalModel?` Optional. Specify which multimodal model to use. Default is GPT4o. See [here](https://docs.cloud.llamaindex.ai/llamaparse/features/multimodal) for a list of available models and cost.
- `vendorMultimodalApiKey?` Optional. Set the multimodal model API key. Can also be set in the environment variable `LLAMA_CLOUD_VENDOR_MULTIMODAL_API_KEY`.
- `numWorkers` as in the python version, is set in `SimpleDirectoryReader`. Default is 1.
### LlamaParse with SimpleDirectoryReader
@@ -8,7 +8,7 @@ In JSON mode, LlamaParse will return a data structure representing the parsed ob
## Usage
For Json mode, you need to use `loadJson`. The `resultType` is automatically set with this method. Currently it can't be used with `SimpleDirectoryReader`.
For Json mode, you need to use `loadJson`. The `resultType` is automatically set with this method.
More information about indexing the results on the next page.
```ts
@@ -0,0 +1,104 @@
# MixedbreadAI
Welcome to the mixedbread embeddings guide! This guide will help you use the mixedbread ai's API to generate embeddings for your text documents, ensuring you get the most relevant information, just like picking the freshest bread from the bakery.
To find out more about the latest features, updates, and available models, visit [mixedbread.ai](https://mixedbread-ai.com/).
## Table of Contents
1. [Setup](#setup)
2. [Usage with LlamaIndex](#integration-with-llamaindex)
3. [Embeddings with Custom Parameters](#embeddings-with-custom-parameters)
## Setup
First, you will need to install the `llamaindex` package.
```bash
pnpm install llamaindex
```
Next, sign up for an API key at [mixedbread.ai](https://mixedbread.ai/). Once you have your API key, you can import the necessary modules and create a new instance of the `MixedbreadAIEmbeddings` class.
```ts
import { MixedbreadAIEmbeddings, Document, Settings } from "llamaindex";
```
## Usage with LlamaIndex
This section will guide you through integrating mixedbread embeddings with LlamaIndex for more advanced usage.
### Step 1: Load and Index Documents
For this example, we will use a single document. In a real-world scenario, you would have multiple documents to index, like a variety of breads in a bakery.
```ts
Settings.embedModel = new MixedbreadAIEmbeddings({
apiKey: "<MIXEDBREAD_API_KEY>",
model: "mixedbread-ai/mxbai-embed-large-v1",
});
const document = new Document({
text: "The true source of happiness.",
id_: "bread",
});
const index = await VectorStoreIndex.fromDocuments([document]);
```
### Step 2: Create a Query Engine
Combine the retriever and the embed model to create a query engine. This setup ensures that your queries are processed to provide the best results, like arranging the bread in the order of freshness and quality.
Models can require prompts to generate embeddings for queries, in the 'mixedbread-ai/mxbai-embed-large-v1' model's case, the prompt is `Represent this sentence for searching relevant passages:`.
```ts
const queryEngine = index.asQueryEngine();
const query =
"Represent this sentence for searching relevant passages: What is bread?";
// Log the response
const results = await queryEngine.query(query);
console.log(results); // Serving up the freshest, most relevant results.
```
## Embeddings with Custom Parameters
This section will guide you through generating embeddings with custom parameters and usage with f.e. matryoshka and binary embeddings.
### Step 1: Create an Instance of MixedbreadAIEmbeddings
Create a new instance of the `MixedbreadAIEmbeddings` class with custom parameters. For example, to use the `mixedbread-ai/mxbai-embed-large-v1` model with a batch size of 64, normalized embeddings, and binary encoding format:
```ts
const embeddings = new MixedbreadAIEmbeddings({
apiKey: "<MIXEDBREAD_API_KEY>",
model: "mixedbread-ai/mxbai-embed-large-v1",
batchSize: 64,
normalized: true,
dimensions: 512,
encodingFormat: MixedbreadAI.EncodingFormat.Binary,
});
```
### Step 2: Define Texts
Define the texts you want to generate embeddings for.
```ts
const texts = ["Bread is life", "Bread is love"];
```
### Step 3: Generate Embeddings
Use the `embedDocuments` method to generate embeddings for the texts.
```ts
const result = await embeddings.embedDocuments(texts);
console.log(result); // Perfectly customized embeddings, ready to serve.
```
## API Reference
- [MixedbreadAIEmbeddings](../../../api/classes/MixedbreadAIEmbeddings.md)
+1 -1
View File
@@ -2,7 +2,7 @@
## Concept
Evaluation and benchmarking are crucial concepts in LLM development. To improve the perfomance of an LLM app (RAG, agents) you must have a way to measure it.
Evaluation and benchmarking are crucial concepts in LLM development. To improve the performance of an LLM app (RAG, agents) you must have a way to measure it.
LlamaIndex offers key modules to measure the quality of generated results. We also offer key modules to measure retrieval quality.
@@ -16,7 +16,7 @@ import {
MetadataMode,
OpenAIEmbedding,
TitleExtractor,
SimpleNodeParser,
SentenceSplitter,
} from "llamaindex";
async function main() {
@@ -29,7 +29,7 @@ async function main() {
const document = new Document({ text: essay, id_: path });
const pipeline = new IngestionPipeline({
transformations: [
new SimpleNodeParser({ chunkSize: 1024, chunkOverlap: 20 }),
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
new TitleExtractor(),
new OpenAIEmbedding(),
],
@@ -62,7 +62,7 @@ import {
MetadataMode,
OpenAIEmbedding,
TitleExtractor,
SimpleNodeParser,
SentenceSplitter,
QdrantVectorStore,
VectorStoreIndex,
} from "llamaindex";
@@ -81,7 +81,7 @@ async function main() {
const document = new Document({ text: essay, id_: path });
const pipeline = new IngestionPipeline({
transformations: [
new SimpleNodeParser({ chunkSize: 1024, chunkOverlap: 20 }),
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
new TitleExtractor(),
new OpenAIEmbedding(),
],
@@ -4,7 +4,7 @@ A transformation is something that takes a list of nodes as an input, and return
Currently, the following components are Transformation objects:
- [SimpleNodeParser](../../api/classes/SimpleNodeParser.md)
- [SentenceSplitter](../../api/classes/SentenceSplitter.md)
- [MetadataExtractor](../documents_and_nodes/metadata_extraction.md)
- [Embeddings](../embeddings/index.md)
@@ -13,10 +13,10 @@ Currently, the following components are Transformation objects:
While transformations are best used with with an IngestionPipeline, they can also be used directly.
```ts
import { SimpleNodeParser, TitleExtractor, Document } from "llamaindex";
import { SentenceSplitter, TitleExtractor, Document } from "llamaindex";
async function main() {
let nodes = new SimpleNodeParser().getNodesFromDocuments([
let nodes = new SentenceSplitter().getNodesFromDocuments([
new Document({ text: "I am 10 years old. John is 20 years old." }),
]);
@@ -34,15 +34,15 @@ main().catch(console.error);
## Custom Transformations
You can implement any transformation yourself by implementing the `TransformerComponent`.
You can implement any transformation yourself by implementing the `TransformComponent`.
The following custom transformation will remove any special characters or punctutaion in text.
The following custom transformation will remove any special characters or punctuation in text.
```ts
import { TransformerComponent, Node } from "llamaindex";
import { TransformComponent, TextNode } from "llamaindex";
class RemoveSpecialCharacters extends TransformerComponent {
async transform(nodes: Node[]): Promise<Node[]> {
export class RemoveSpecialCharacters extends TransformComponent {
async transform(nodes: TextNode[]): Promise<TextNode[]> {
for (const node of nodes) {
node.text = node.text.replace(/[^\w\s]/gi, "");
}
@@ -75,3 +75,7 @@ async function main() {
main().catch(console.error);
```
## API Reference
- [TransformComponent](../../api/classes/TransformComponent.md)
@@ -15,7 +15,7 @@ Settings.llm = new Bedrock({
});
```
Currently only supports Anthropic models:
Currently only supports Anthropic and Meta models:
```ts
ANTHROPIC_CLAUDE_INSTANT_1 = "anthropic.claude-instant-v1";
@@ -25,6 +25,13 @@ ANTHROPIC_CLAUDE_3_SONNET = "anthropic.claude-3-sonnet-20240229-v1:0";
ANTHROPIC_CLAUDE_3_HAIKU = "anthropic.claude-3-haiku-20240307-v1:0";
ANTHROPIC_CLAUDE_3_OPUS = "anthropic.claude-3-opus-20240229-v1:0"; // available on us-west-2
ANTHROPIC_CLAUDE_3_5_SONNET = "anthropic.claude-3-5-sonnet-20240620-v1:0";
META_LLAMA2_13B_CHAT = "meta.llama2-13b-chat-v1";
META_LLAMA2_70B_CHAT = "meta.llama2-70b-chat-v1";
META_LLAMA3_8B_INSTRUCT = "meta.llama3-8b-instruct-v1:0";
META_LLAMA3_70B_INSTRUCT = "meta.llama3-70b-instruct-v1:0";
META_LLAMA3_1_8B_INSTRUCT = "meta.llama3-1-8b-instruct-v1:0"; // available on us-west-2
META_LLAMA3_1_70B_INSTRUCT = "meta.llama3-1-70b-instruct-v1:0"; // available on us-west-2
META_LLAMA3_1_405B_INSTRUCT = "meta.llama3-1-405b-instruct-v1:0"; // preview only, available on us-west-2, tool calling supported
```
Sonnet, Haiku and Opus are multimodal, image_url only supports base64 data url format, e.g. `data:image/jpeg;base64,SGVsbG8sIFdvcmxkIQ==`
@@ -60,3 +67,72 @@ async function main() {
console.log(response.response);
}
```
## Agent Example
```ts
import { BEDROCK_MODELS, Bedrock } from "@llamaindex/community";
import { FunctionTool, LLMAgent } from "llamaindex";
const sumNumbers = FunctionTool.from(
({ a, b }: { a: number; b: number }) => `${a + b}`,
{
name: "sumNumbers",
description: "Use this function to sum two numbers",
parameters: {
type: "object",
properties: {
a: {
type: "number",
description: "The first number",
},
b: {
type: "number",
description: "The second number",
},
},
required: ["a", "b"],
},
},
);
const divideNumbers = FunctionTool.from(
({ a, b }: { a: number; b: number }) => `${a / b}`,
{
name: "divideNumbers",
description: "Use this function to divide two numbers",
parameters: {
type: "object",
properties: {
a: {
type: "number",
description: "The dividend a to divide",
},
b: {
type: "number",
description: "The divisor b to divide by",
},
},
required: ["a", "b"],
},
},
);
const bedrock = new Bedrock({
model: BEDROCK_MODELS.META_LLAMA3_1_405B_INSTRUCT,
...
});
async function main() {
const agent = new LLMAgent({
llm: bedrock,
tools: [sumNumbers, divideNumbers],
});
const response = await agent.chat({
message: "How much is 5 + 5? then divide by 2",
});
console.log(response.message);
}
```
@@ -0,0 +1,52 @@
# DeepSeek LLM
[DeepSeek Platform](https://platform.deepseek.com/)
## Usage
```ts
import { DeepSeekLLM, Settings } from "llamaindex";
Settings.llm = new DeepSeekLLM({
apiKey: "<YOUR_API_KEY>",
model: "deepseek-coder", // or "deepseek-chat"
});
```
## Example
```ts
import { DeepSeekLLM, Document, VectorStoreIndex, Settings } from "llamaindex";
const deepseekLlm = new DeepSeekLLM({
apiKey: "<YOUR_API_KEY>",
model: "deepseek-coder", // or "deepseek-chat"
});
async function main() {
const response = await llm.deepseekLlm.chat({
messages: [
{
role: "system",
content: "You are an AI assistant",
},
{
role: "user",
content: "Tell me about San Francisco",
},
],
stream: false,
});
console.log(response);
}
```
# Limitations
Currently does not support function calling.
[Currently does not support json-output param while still is very good at json generating.](https://platform.deepseek.com/api-docs/faq#does-your-api-support-json-output)
## API Reference
- [DeepSeekLLM](../../../api/classes/DeepSeekLLM.md)
+2 -3
View File
@@ -7,9 +7,9 @@ sidebar_position: 4
The `NodeParser` in LlamaIndex is responsible for splitting `Document` objects into more manageable `Node` objects. When you call `.fromDocuments()`, the `NodeParser` from the `Settings` is used to do this automatically for you. Alternatively, you can use it to split documents ahead of time.
```typescript
import { Document, SimpleNodeParser } from "llamaindex";
import { Document, SentenceSplitter } from "llamaindex";
const nodeParser = new SimpleNodeParser();
const nodeParser = new SentenceSplitter();
Settings.nodeParser = nodeParser;
```
@@ -93,6 +93,5 @@ The output metadata will be something like:
## API Reference
- [SimpleNodeParser](../api/classes/SimpleNodeParser.md)
- [SentenceSplitter](../api/classes/SentenceSplitter.md)
- [MarkdownNodeParser](../api/classes/MarkdownNodeParser.md)
@@ -39,8 +39,9 @@ const index = await VectorStoreIndex.fromDocuments([document]);
The default value for `similarityTopK` is 2. This means that only the most similar document will be returned. To retrieve more results, you can increase the value of `similarityTopK`.
```ts
const retriever = index.asRetriever();
retriever.similarityTopK = 5;
const retriever = index.asRetriever({
similarityTopK: 5,
});
```
## Create a new instance of the CohereRerank class
@@ -39,8 +39,9 @@ const index = await VectorStoreIndex.fromDocuments([document]);
The default value for `similarityTopK` is 2. This means that only the most similar document will be returned. To retrieve more results, you can increase the value of `similarityTopK`.
```ts
const retriever = index.asRetriever();
retriever.similarityTopK = 5;
const retriever = index.asRetriever({
similarityTopK: 5,
});
```
## Create a new instance of the JinaAIReranker class
@@ -0,0 +1,169 @@
# MixedbreadAI
Welcome to the mixedbread ai reranker guide! This guide will help you use mixedbread ai's API to rerank search query results, ensuring you get the most relevant information, just like picking the freshest bread from the bakery.
To find out more about the latest features and updates, visit the [mixedbread.ai](https://mixedbread.ai/).
## Table of Contents
1. [Setup](#setup)
2. [Usage with LlamaIndex](#integration-with-llamaindex)
3. [Simple Reranking Guide](#simple-reranking-guide)
4. [Reranking with Objects](#reranking-with-objects)
## Setup
First, you will need to install the `llamaindex` package.
```bash
pnpm install llamaindex
```
Next, sign up for an API key at [mixedbread.ai](https://mixedbread.ai/). Once you have your API key, you can import the necessary modules and create a new instance of the `MixedbreadAIReranker` class.
```ts
import {
MixedbreadAIReranker,
Document,
OpenAI,
VectorStoreIndex,
Settings,
} from "llamaindex";
```
## Usage with LlamaIndex
This section will guide you through integrating mixedbread's reranker with LlamaIndex.
### Step 1: Load and Index Documents
For this example, we will use a single document. In a real-world scenario, you would have multiple documents to index, like a variety of breads in a bakery.
```ts
const document = new Document({
text: "This is a sample document.",
id_: "sampleDoc",
});
Settings.llm = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0.1 });
const index = await VectorStoreIndex.fromDocuments([document]);
```
### Step 2: Increase Similarity TopK
The default value for `similarityTopK` is 2, which means only the most similar document will be returned. To get more results, like picking a variety of fresh breads, you can increase the value of `similarityTopK`.
```ts
const retriever = index.asRetriever({
similarityTopK: 5,
});
```
### Step 3: Create a MixedbreadAIReranker Instance
Create a new instance of the `MixedbreadAIReranker` class.
```ts
const nodePostprocessor = new MixedbreadAIReranker({
apiKey: "<MIXEDBREAD_API_KEY>",
topN: 4,
});
```
### Step 4: Create a Query Engine
Combine the retriever and node postprocessor to create a query engine. This setup ensures that your queries are processed and reranked to provide the best results, like arranging the bread in the order of freshness and quality.
```ts
const queryEngine = index.asQueryEngine({
retriever,
nodePostprocessors: [nodePostprocessor],
});
// Log the response
const response = await queryEngine.query("Where did the author grow up?");
console.log(response);
```
With mixedbread's Reranker, you're all set to serve up the most relevant and well-ordered results, just like a skilled baker arranging their best breads for eager customers. Enjoy the perfect blend of technology and culinary delight!
## Simple Reranking Guide
This section will guide you through a simple reranking process using mixedbread ai.
### Step 1: Create an Instance of MixedbreadAIReranker
Create a new instance of the `MixedbreadAIReranker` class, passing in your API key and the number of results you want to return. It's like setting up your bakery to offer a specific number of freshly baked items.
```ts
const reranker = new MixedbreadAIReranker({
apiKey: "<MIXEDBREAD_API_KEY>",
topN: 4,
});
```
### Step 2: Define Nodes and Query
Define the nodes (documents) you want to rerank and the query.
```ts
const nodes = [
{ node: new BaseNode("To bake bread you need flour") },
{ node: new BaseNode("To bake bread you need yeast") },
];
const query = "What do you need to bake bread?";
```
### Step 3: Perform Reranking
Use the `postprocessNodes` method to rerank the nodes based on the query.
```ts
const result = await reranker.postprocessNodes(nodes, query);
console.log(result); // Like pulling freshly baked nodes out of the oven.
```
## Reranking with Objects
This section will guide you through reranking when working with objects.
### Step 1: Create an Instance of MixedbreadAIReranker
Create a new instance of the `MixedbreadAIReranker` class, just like before.
```ts
const reranker = new MixedbreadAIReranker({
apiKey: "<MIXEDBREAD_API_KEY>",
model: "mixedbread-ai/mxbai-rerank-large-v1",
topK: 5,
rankFields: ["title", "content"],
returnInput: true,
maxRetries: 5,
});
```
### Step 2: Define Documents and Query
Define the documents (objects) you want to rerank and the query.
```ts
const documents = [
{ title: "Bread Recipe", content: "To bake bread you need flour" },
{ title: "Bread Recipe", content: "To bake bread you need yeast" },
];
const query = "What do you need to bake bread?";
```
### Step 3: Perform Reranking
Use the `rerank` method to reorder the documents based on the query.
```ts
const result = await reranker.rerank(documents, query);
console.log(result); // Perfectly customized results, ready to serve.
```
## API Reference
- [MixedbreadAIReranker](../../api/classes/MixedbreadAIReranker.md)
@@ -1,6 +1,6 @@
# QueryEngine
A query engine wraps a `Retriever` and a `ResponseSynthesizer` into a pipeline, that will use the query string to fetech nodes and then send them to the LLM to generate a response.
A query engine wraps a `Retriever` and a `ResponseSynthesizer` into a pipeline, that will use the query string to fetch nodes and then send them to the LLM to generate a response.
```typescript
const queryEngine = index.asQueryEngine();
@@ -75,7 +75,7 @@ const queryEngine = index.asQueryEngine({
{
key: "dogId",
value: "2",
filterType: "ExactMatch",
operator: "==",
},
],
},
@@ -88,6 +88,8 @@ const response = await queryEngine.query({
console.log(response.toString());
```
Besides using the equal operator (`==`), you can also use a whole set of different [operators](../../api/interfaces/MetadataFilter.md#operator) to filter your documents.
## Full Code
```ts
@@ -135,7 +137,7 @@ async function main() {
{
key: "dogId",
value: "2",
filterType: "ExactMatch",
operator: "==",
},
],
},
@@ -156,3 +158,4 @@ main();
- [VectorStoreIndex](../../api/classes/VectorStoreIndex.md)
- [ChromaVectorStore](../../api/classes/ChromaVectorStore.md)
- [MetadataFilter](../../api/interfaces/MetadataFilter.md)
@@ -15,7 +15,7 @@ import {
OpenAI,
RouterQueryEngine,
SimpleDirectoryReader,
SimpleNodeParser,
SentenceSplitter,
SummaryIndex,
VectorStoreIndex,
Settings,
@@ -34,11 +34,11 @@ const documents = await new SimpleDirectoryReader().loadData({
## Service Context
Next, we need to define some basic rules and parse the documents into nodes. We will use the `SimpleNodeParser` to parse the documents into nodes and `Settings` to define the rules (eg. LLM API key, chunk size, etc.):
Next, we need to define some basic rules and parse the documents into nodes. We will use the `SentenceSplitter` to parse the documents into nodes and `Settings` to define the rules (eg. LLM API key, chunk size, etc.):
```ts
Settings.llm = new OpenAI();
Settings.nodeParser = new SimpleNodeParser({
Settings.nodeParser = new SentenceSplitter({
chunkSize: 1024,
});
```
@@ -104,14 +104,14 @@ import {
OpenAI,
RouterQueryEngine,
SimpleDirectoryReader,
SimpleNodeParser,
SentenceSplitter,
SummaryIndex,
VectorStoreIndex,
Settings,
} from "llamaindex";
Settings.llm = new OpenAI();
Settings.nodeParser = new SimpleNodeParser({
Settings.nodeParser = new SentenceSplitter({
chunkSize: 1024,
});
+11 -9
View File
@@ -4,18 +4,20 @@ sidebar_position: 5
# Retriever
A retriever in LlamaIndex is what is used to fetch `Node`s from an index using a query string. Aa `VectorIndexRetriever` will fetch the top-k most similar nodes. Meanwhile, a `SummaryIndexRetriever` will fetch all nodes no matter the query.
A retriever in LlamaIndex is what is used to fetch `Node`s from an index using a query string.
- [VectorIndexRetriever](../api/classes/VectorIndexRetriever.md) will fetch the top-k most similar nodes. Ideal for dense retrieval to find most relevant nodes.
- [SummaryIndexRetriever](../api/classes/SummaryIndexRetriever.md) will fetch all nodes no matter the query. Ideal when complete context is necessary, e.g. analyzing large datasets.
- [SummaryIndexLLMRetriever](../api/classes/SummaryIndexLLMRetriever.md) utilizes an LLM to score and filter nodes based on relevancy to the query.
- [KeywordTableLLMRetriever](../api/classes/KeywordTableLLMRetriever.md) uses an LLM to extract keywords from the query and retrieve relevant nodes based on keyword matches.
- [KeywordTableSimpleRetriever](../api/classes/KeywordTableSimpleRetriever.md) uses a basic frequency-based approach to extract keywords and retrieve nodes.
- [KeywordTableRAKERetriever](../api/classes/KeywordTableRAKERetriever.md) uses the RAKE (Rapid Automatic Keyword Extraction) algorithm to extract keywords from the query, focusing on co-occurrence and context for keyword-based retrieval.
```typescript
const retriever = vector_index.asRetriever();
retriever.similarityTopK = 3;
const retriever = vectorIndex.asRetriever({
similarityTopK: 3,
});
// Fetch nodes!
const nodesWithScore = await retriever.retrieve({ query: "query string" });
```
## API Reference
- [SummaryIndexRetriever](../api/classes/SummaryIndexRetriever.md)
- [SummaryIndexLLMRetriever](../api/classes/SummaryIndexLLMRetriever.md)
- [VectorIndexRetriever](../api/classes/VectorIndexRetriever.md)
+37 -3
View File
@@ -4,12 +4,19 @@ sidebar_position: 7
# Storage
Storage in LlamaIndex.TS works automatically once you've configured a `StorageContext` object. Just configure the `persistDir` and attach it to an index.
Storage in LlamaIndex.TS works automatically once you've configured a
`StorageContext` object.
Right now, only saving and loading from disk is supported, with future integrations planned!
## Local Storage
You can configure the `persistDir` and attach it to an index.
```typescript
import { Document, VectorStoreIndex, storageContextFromDefaults } from "./src";
import {
Document,
VectorStoreIndex,
storageContextFromDefaults,
} from "llamaindex";
const storageContext = await storageContextFromDefaults({
persistDir: "./storage",
@@ -21,6 +28,33 @@ const index = await VectorStoreIndex.fromDocuments([document], {
});
```
## PostgreSQL Storage
You can configure the `schemaName`, `tableName`, `namespace`, and
`connectionString`. If a `connectionString` is not
provided, it will use the environment variables `PGHOST`, `PGUSER`,
`PGPASSWORD`, `PGDATABASE` and `PGPORT`.
```typescript
import {
Document,
VectorStoreIndex,
PostgresDocumentStore,
PostgresIndexStore,
storageContextFromDefaults,
} from "llamaindex";
const storageContext = await storageContextFromDefaults({
docStore: new PostgresDocumentStore(),
indexStore: new PostgresIndexStore(),
});
const document = new Document({ text: "Test Text" });
const index = await VectorStoreIndex.fromDocuments([document], {
storageContext,
});
```
## API Reference
- [StorageContext](../api/interfaces/StorageContext.md)
+168
View File
@@ -0,0 +1,168 @@
import CodeBlock from "@theme/CodeBlock";
import CodeSource from "!raw-loader!../../../../examples/workflow/joke.ts";
# Workflows
A `Workflow` in LlamaIndexTS is an event-driven abstraction used to chain together several events. Workflows are made up of `steps`, with each step responsible for handling certain event types and emitting new events.
Workflows in LlamaIndexTS work by defining step functions that handle specific event types and emit new events.
When a step function is added to a workflow, you need to specify the input and optionally the output event types (used for validation). The specification of the input events ensures each step only runs when an accepted event is ready.
You can create a `Workflow` to do anything! Build an agent, a RAG flow, an extraction flow, or anything else you want.
## Getting Started
As an illustrative example, let's consider a naive workflow where a joke is generated and then critiqued.
<CodeBlock language="ts">{CodeSource}</CodeBlock>
There's a few moving pieces here, so let's go through this piece by piece.
### Defining Workflow Events
```typescript
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
```
Events are user-defined classes that extend `WorkflowEvent` and contain arbitrary data provided as template argument. In this case, our workflow relies on a single user-defined event, the `JokeEvent` with a `joke` attribute of type `string`.
### Setting up the Workflow Class
```typescript
const llm = new OpenAI();
...
const jokeFlow = new Workflow({ verbose: true });
```
Our workflow is implemented by initiating the `Workflow` class. For simplicity, we created a `OpenAI` llm instance.
### Workflow Entry Points
```typescript
const generateJoke = async (_context: Context, ev: StartEvent) => {
const prompt = `Write your best joke about ${ev.data.input}.`;
const response = await llm.complete({ prompt });
return new JokeEvent({ joke: response.text });
};
```
Here, we come to the entry-point of our workflow. While events are user-defined, there are two special-case events, the `StartEvent` and the `StopEvent`. Here, the `StartEvent` signifies where to send the initial workflow input.
The `StartEvent` is a bit of a special object since it can hold arbitrary attributes. Here, we accessed the topic with `ev.data.input`.
At this point, you may have noticed that we haven't explicitly told the workflow what events are handled by which steps.
To do so, we use the `addStep` method which adds a step to the workflow. The first argument is the event type that the step will handle, and the second argument is the previously defined step function:
```typescript
jokeFlow.addStep(StartEvent, generateJoke);
```
### Workflow Exit Points
```typescript
const critiqueJoke = async (_context: Context, ev: JokeEvent) => {
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
const response = await llm.complete({ prompt });
return new StopEvent({ result: response.text });
};
```
Here, we have our second, and last step, in the workflow. We know its the last step because the special `StopEvent` is returned. When the workflow encounters a returned `StopEvent`, it immediately stops the workflow and returns whatever the result was.
In this case, the result is a string, but it could be a map, array, or any other object.
Don't forget to add the step to the workflow:
```typescript
jokeFlow.addStep(JokeEvent, critiqueJoke);
```
### Running the Workflow
```typescript
const result = await jokeFlow.run("pirates");
console.log(result.data.result);
```
Lastly, we run the workflow. The `.run()` method is async, so we use await here to wait for the result.
### Validating Workflows
To tell the workflow what events are produced by each step, you can optionally provide a third argument to `addStep` to specify the output event type:
```typescript
jokeFlow.addStep(StartEvent, generateJoke, { outputs: JokeEvent });
jokeFlow.addStep(JokeEvent, critiqueJoke, { outputs: StopEvent });
```
To validate a workflow, you need to call the `validate` method:
```typescript
jokeFlow.validate();
```
To automatically validate a workflow when you run it, you can set the `validate` flag to `true` at initialization:
```typescript
const jokeFlow = new Workflow({ verbose: true, validate: true });
```
## Working with Global Context/State
Optionally, you can choose to use global context between steps. For example, maybe multiple steps access the original `query` input from the user. You can store this in global context so that every step has access.
```typescript
import { Context } from "@llamaindex/core/workflow";
const query = async (context: Context, ev: MyEvent) => {
// get the query from the context
const query = context.get("query");
// do something with context and event
const val = ...
const result = ...
// store in context
context.set("key", val);
return new StopEvent({ result });
};
```
## Waiting for Multiple Events
The context does more than just hold data, it also provides utilities to buffer and wait for multiple events.
For example, you might have a step that waits for a query and retrieved nodes before synthesizing a response:
```typescript
const synthesize = async (context: Context, ev: QueryEvent | RetrieveEvent) => {
const events = context.collectEvents(ev, [QueryEvent | RetrieveEvent]);
if (!events) {
return;
}
const prompt = events
.map((event) => {
if (event instanceof QueryEvent) {
return `Answer this query using the context provided: ${event.data.query}`;
} else if (event instanceof RetrieveEvent) {
return `Context: ${event.data.context}`;
}
return "";
})
.join("\n");
const response = await llm.complete({ prompt });
return new StopEvent({ result: response.text });
};
```
Using `ctx.collectEvents()` we can buffer and wait for ALL expected events to arrive. This function will only return events (in the requested order) once all events have arrived.
## Manually Triggering Events
Normally, events are triggered by returning another event during a step. However, events can also be manually dispatched using the `ctx.sendEvent(event)` method within a workflow.
## Examples
You can find many useful examples of using workflows in the [examples folder](https://github.com/run-llama/LlamaIndexTS/blob/main/examples/workflow).
+20 -20
View File
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.32",
"version": "0.0.69",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
@@ -15,29 +15,29 @@
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "^3.3.2",
"@docusaurus/remark-plugin-npm2yarn": "^3.3.2",
"@docusaurus/core": "3.5.2",
"@docusaurus/remark-plugin-npm2yarn": "3.5.2",
"@llamaindex/examples": "workspace:*",
"@mdx-js/react": "^3.0.1",
"clsx": "^2.1.1",
"@mdx-js/react": "3.0.1",
"clsx": "2.1.1",
"llamaindex": "workspace:*",
"postcss": "^8.4.38",
"prism-react-renderer": "^2.3.1",
"raw-loader": "^4.0.2",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"postcss": "8.4.41",
"prism-react-renderer": "2.4.0",
"raw-loader": "4.0.2",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.3.2",
"@docusaurus/preset-classic": "^3.3.2",
"@docusaurus/theme-classic": "^3.3.2",
"@docusaurus/types": "^3.3.2",
"@tsconfig/docusaurus": "^2.0.3",
"@types/node": "^20.12.11",
"docusaurus-plugin-typedoc": "^1.0.1",
"typedoc": "^0.25.13",
"typedoc-plugin-markdown": "^4.0.1",
"typescript": "^5.5.2"
"@docusaurus/module-type-aliases": "3.5.2",
"@docusaurus/preset-classic": "3.5.2",
"@docusaurus/theme-classic": "3.5.2",
"@docusaurus/types": "3.5.2",
"@tsconfig/docusaurus": "2.0.3",
"@types/node": "^22.5.1",
"docusaurus-plugin-typedoc": "1.0.5",
"typedoc": "0.26.6",
"typedoc-plugin-markdown": "4.2.6",
"typescript": "^5.5.4"
},
"browserslist": {
"production": [
+19
View File
@@ -1,5 +1,24 @@
# examples
## 0.0.8
### Patch Changes
- 11feef8: Add workflows
- Updated dependencies [11feef8]
- @llamaindex/core@0.2.0
- llamaindex@0.6.0
## 0.0.7
### Patch Changes
- Updated dependencies [16ef5dd]
- Updated dependencies [16ef5dd]
- Updated dependencies [36ddec4]
- llamaindex@0.5.0
- @llamaindex/core@0.1.0
## 0.0.6
### Patch Changes
+1 -1
View File
@@ -9,7 +9,7 @@ make sure you have basic knowledge of the [LlamaIndexTS](https://ts.llamaindex.a
# export your API key
export OPENAI_API_KEY="sk-..."
npx ts-node ./chatEngine.ts
npx tsx ./chatEngine.ts
```
## Build your own RAG app
+54
View File
@@ -0,0 +1,54 @@
import "dotenv/config";
import {
DefaultAzureCredential,
getBearerTokenProvider,
} from "@azure/identity";
import { AzureDynamicSessionTool, OpenAI, ReActAgent } from "llamaindex";
async function main() {
const credential = new DefaultAzureCredential();
const azureADTokenProvider = getBearerTokenProvider(
credential,
"https://cognitiveservices.azure.com/.default",
);
const azure = {
azureADTokenProvider,
deployment: process.env.AZURE_OPENAI_DEPLOYMENT ?? "gpt-35-turbo",
};
// configure LLM model
const llm = new OpenAI({
azure,
});
const azureDynamicSession = new AzureDynamicSessionTool();
// Create an ReActAgent with the azure dynamic session tool
const agent = new ReActAgent({
llm,
tools: [azureDynamicSession],
// verbose: true,
systemPrompt: `You are a Python interpreter.
- You are given tasks to complete and you run python code to solve them.
- The python code runs by the python runtime. Every time you call $(interpreter) tool, the python code is executed in a separate cell. It's okay to make multiple calls to $(interpreter).
- You can run any python code you want in a secure environment.
- For images, return the full URL, not the base64 data.
- Return any image content as an HTML tag with the src attribute set to the URL of the image.`,
});
// Chat with the agent
const response = await agent.chat({
message:
"plot a chart of 5 random numbers and save it to /mnt/data/chart.png",
stream: false,
});
// Print the response
console.log({ response });
}
void main().then(() => {
console.log("Done");
});
+2 -2
View File
@@ -6,8 +6,8 @@ import {
OpenAI,
OpenAIAgent,
QueryEngineTool,
SentenceSplitter,
Settings,
SimpleNodeParser,
SimpleToolNodeMapping,
SummaryIndex,
VectorStoreIndex,
@@ -43,7 +43,7 @@ async function main() {
for (const title of wikiTitles) {
console.log(`Processing ${title}`);
const nodes = new SimpleNodeParser({
const nodes = new SentenceSplitter({
chunkSize: 200,
chunkOverlap: 20,
}).getNodesFromDocuments([countryDocs[title]]);
-1
View File
@@ -1,5 +1,4 @@
import { ChatResponseChunk, OpenAIAgent } from "llamaindex";
import { ReadableStream } from "node:stream/web";
import {
getCurrentIDTool,
getUserInfoTool,
-1
View File
@@ -1,5 +1,4 @@
import { ChatResponseChunk, ReActAgent } from "llamaindex";
import { ReadableStream } from "node:stream/web";
import {
getCurrentIDTool,
getUserInfoTool,
+1 -1
View File
@@ -2,7 +2,7 @@ import { Anthropic, FunctionTool, Settings, WikipediaTool } from "llamaindex";
import { AnthropicAgent } from "llamaindex/agent/anthropic";
Settings.callbackManager.on("llm-tool-call", (event) => {
console.log("llm-tool-call", event.detail.payload.toolCall);
console.log("llm-tool-call", event.detail.toolCall);
});
const anthropic = new Anthropic({
+3 -3
View File
@@ -24,7 +24,7 @@ Here are two sample scripts which work well with the sample data in the Astra Po
Loads and queries a simple vectorstore with some documents about Astra DB
run `ts-node astradb/example`
run `tsx astradb/example`
## Movie Reviews Example
@@ -32,10 +32,10 @@ run `ts-node astradb/example`
This sample loads the same dataset of movie reviews as the Astra Portal sample dataset. (Feel free to load the data in your the Astra Data Explorer to compare)
run `npx ts-node astradb/load`
run `npx tsx astradb/load`
### Use RAG to Query the data
Check out your data in the Astra Data Explorer and change the sample query as you see fit.
run `npx ts-node astradb/query`
run `npx tsx astradb/query`
+3 -2
View File
@@ -16,8 +16,9 @@ Settings.chunkSize = 512;
async function main() {
const document = new Document({ text: essay });
const index = await VectorStoreIndex.fromDocuments([document]);
const retriever = index.asRetriever();
retriever.similarityTopK = 5;
const retriever = index.asRetriever({
similarityTopK: 5,
});
const chatEngine = new ContextChatEngine({ retriever });
const rl = readline.createInterface({ input, output });
+1 -1
View File
@@ -6,7 +6,7 @@ Export your OpenAI API Key using `export OPEN_API_KEY=insert your api key here`
If you haven't installed chromadb, run `pip install chromadb`. Start the server using `chroma run`.
Now, open a new terminal window and inside `examples`, run `pnpm dlx ts-node chromadb/test.ts`.
Now, open a new terminal window and inside `examples`, run `pnpm dlx tsx chromadb/test.ts`.
Here's the output for the input query `Tell me about Godfrey Cheshire's rating of La Sapienza.`:
+1 -1
View File
@@ -40,7 +40,7 @@ async function main() {
{
key: "dogId",
value: "2",
filterType: "ExactMatch",
operator: "==",
},
],
},
+3 -3
View File
@@ -21,7 +21,7 @@ export LLAMA_CLOUD_BASE_URL="https://api.staging.llamaindex.ai"
This example is using the managed index named `test` from the project `default` to create a chat engine.
```shell
pnpx ts-node cloud/chat.ts
pnpx tsx cloud/chat.ts
```
## Query Engine
@@ -29,7 +29,7 @@ pnpx ts-node cloud/chat.ts
This example shows how to use the managed index with a query engine.
```shell
pnpx ts-node cloud/query.ts
pnpx tsx cloud/query.ts
```
## Pipeline
@@ -37,5 +37,5 @@ pnpx ts-node cloud/query.ts
This example shows how to create a managed index with a pipeline.
```shell
pnpx ts-node cloud/pipeline.ts
pnpx tsx cloud/pipeline.ts
```
+2 -2
View File
@@ -6,7 +6,7 @@ import { ContextChatEngine, LlamaCloudIndex } from "llamaindex";
async function main() {
const index = new LlamaCloudIndex({
name: "test",
projectName: "default",
projectName: "Default",
baseUrl: process.env.LLAMA_CLOUD_BASE_URL,
apiKey: process.env.LLAMA_CLOUD_API_KEY,
});
@@ -19,10 +19,10 @@ async function main() {
while (true) {
const query = await rl.question("User: ");
const stream = await chatEngine.chat({ message: query, stream: true });
console.log();
for await (const chunk of stream) {
process.stdout.write(chunk.response);
}
process.stdout.write("\n");
}
}
+1 -1
View File
@@ -3,7 +3,7 @@ import { DeepInfraEmbedding } from "llamaindex";
async function main() {
// API token can be provided as an environment variable too
// using DEEPINFRA_API_TOKEN variable
const apiToken = "YOUR_API_TOKEN" ?? process.env.DEEPINFRA_API_TOKEN;
const apiToken = process.env.DEEPINFRA_API_TOKEN ?? "YOUR_API_TOKEN";
const model = "BAAI/bge-large-en-v1.5";
const embedModel = new DeepInfraEmbedding({
model,
+2 -2
View File
@@ -2,13 +2,13 @@ import {
Document,
KeywordExtractor,
OpenAI,
SimpleNodeParser,
SentenceSplitter,
} from "llamaindex";
(async () => {
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0 });
const nodeParser = new SimpleNodeParser();
const nodeParser = new SentenceSplitter();
const nodes = nodeParser.getNodesFromDocuments([
new Document({ text: "banana apple orange pear peach watermelon" }),
@@ -2,13 +2,13 @@ import {
Document,
OpenAI,
QuestionsAnsweredExtractor,
SimpleNodeParser,
SentenceSplitter,
} from "llamaindex";
(async () => {
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0 });
const nodeParser = new SimpleNodeParser();
const nodeParser = new SentenceSplitter();
const nodes = nodeParser.getNodesFromDocuments([
new Document({
+2 -2
View File
@@ -1,14 +1,14 @@
import {
Document,
OpenAI,
SimpleNodeParser,
SentenceSplitter,
SummaryExtractor,
} from "llamaindex";
(async () => {
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo", temperature: 0 });
const nodeParser = new SimpleNodeParser();
const nodeParser = new SentenceSplitter();
const nodes = nodeParser.getNodesFromDocuments([
new Document({
+2 -2
View File
@@ -1,11 +1,11 @@
import { Document, OpenAI, SimpleNodeParser, TitleExtractor } from "llamaindex";
import { Document, OpenAI, SentenceSplitter, TitleExtractor } from "llamaindex";
import essay from "../essay";
(async () => {
const openaiLLM = new OpenAI({ model: "gpt-3.5-turbo-0125", temperature: 0 });
const nodeParser = new SimpleNodeParser({});
const nodeParser = new SentenceSplitter({});
const nodes = nodeParser.getNodesFromDocuments([
new Document({
+2 -5
View File
@@ -7,10 +7,7 @@
"metadata": {},
"outputs": [],
"source": [
"import {\n",
" Document,\n",
" SimpleNodeParser\n",
"} from \"npm:llamaindex\";"
"import { Document, SentenceSplitter } from \"npm:llamaindex\";"
]
},
{
@@ -45,7 +42,7 @@
}
],
"source": [
"const nodeParser = new SimpleNodeParser();\n",
"const nodeParser = new SentenceSplitter();\n",
"const nodes = nodeParser.getNodesFromDocuments([\n",
" new Document({ text: \"I am 10 years old. John is 20 years old.\" }),\n",
"]);\n",
+2 -3
View File
@@ -1,17 +1,16 @@
import {
Document,
SentenceSplitter,
Settings,
SimpleNodeParser,
VectorStoreIndex,
} from "llamaindex";
export const STORAGE_DIR = "./data";
// Update node parser
Settings.nodeParser = new SimpleNodeParser({
Settings.nodeParser = new SentenceSplitter({
chunkSize: 512,
chunkOverlap: 20,
splitLongSentences: true,
});
(async () => {
// generate a document with a very long sentence (9000 words long)
+9 -7
View File
@@ -2,12 +2,12 @@ import {
Document,
NodeWithScore,
ResponseSynthesizer,
SimpleNodeParser,
SentenceSplitter,
TextNode,
} from "llamaindex";
(async () => {
const nodeParser = new SimpleNodeParser();
const nodeParser = new SentenceSplitter();
const nodes = nodeParser.getNodesFromDocuments([
new Document({ text: "I am 10 years old. John is 20 years old." }),
]);
@@ -27,11 +27,13 @@ import {
},
];
const stream = await responseSynthesizer.synthesize({
query: "What age am I?",
nodesWithScore,
stream: true,
});
const stream = await responseSynthesizer.synthesize(
{
query: "What age am I?",
nodesWithScore,
},
true,
);
for await (const chunk of stream) {
process.stdout.write(chunk.response);
}
+40
View File
@@ -0,0 +1,40 @@
import { MilvusVectorStore, VectorStoreIndex } from "llamaindex";
const collectionName = "movie_reviews";
async function main() {
try {
const milvus = new MilvusVectorStore({ collection: collectionName });
const index = await VectorStoreIndex.fromVectorStore(milvus);
const retriever = index.asRetriever({ similarityTopK: 20 });
console.log("\n=====\nQuerying the index with filters");
const queryEngineWithFilters = index.asQueryEngine({
retriever,
preFilters: {
filters: [
{
key: "document_id",
value: "./data/movie_reviews.csv_37",
operator: "==",
},
{
key: "document_id",
value: "./data/movie_reviews.csv_37",
operator: "!=",
},
],
condition: "or",
},
});
const resultAfterFilter = await queryEngineWithFilters.query({
query: "Get all movie titles.",
});
console.log(`Query from ${resultAfterFilter.sourceNodes?.length} nodes`);
console.log(resultAfterFilter.response);
} catch (e) {
console.error(e);
}
}
void main();
+143
View File
@@ -0,0 +1,143 @@
import {
Document,
Settings,
SimpleDocumentStore,
VectorStoreIndex,
storageContextFromDefaults,
} from "llamaindex";
Settings.callbackManager.on("retrieve-end", (event) => {
const { nodes } = event.detail;
console.log("Number of retrieved nodes:", nodes.length);
});
async function getDataSource() {
const docs = [
new Document({
text: "The dog is brown",
metadata: {
dogId: "1",
private: true,
},
}),
new Document({
text: "The dog is yellow",
metadata: {
dogId: "2",
private: false,
},
}),
new Document({
text: "The dog is red",
metadata: {
dogId: "3",
private: false,
},
}),
];
const storageContext = await storageContextFromDefaults({
persistDir: "./cache",
});
const numberOfDocs = Object.keys(
(storageContext.docStore as SimpleDocumentStore).toDict(),
).length;
if (numberOfDocs === 0) {
// Generate the data source if it's empty
return await VectorStoreIndex.fromDocuments(docs, {
storageContext,
});
}
return await VectorStoreIndex.init({
storageContext,
});
}
async function main() {
const index = await getDataSource();
console.log(
"=============\nQuerying index with no filters. The output should be any color.",
);
const queryEngineNoFilters = index.asQueryEngine({
similarityTopK: 3,
});
const noFilterResponse = await queryEngineNoFilters.query({
query: "What is the color of the dog?",
});
console.log("No filter response:", noFilterResponse.toString());
console.log(
"\n=============\nQuerying index with dogId 2 and private false. The output always should be red.",
);
const queryEngineEQ = index.asQueryEngine({
preFilters: {
filters: [
{
key: "private",
value: "false",
operator: "==",
},
{
key: "dogId",
value: "3",
operator: "==",
},
],
},
similarityTopK: 3,
});
const responseEQ = await queryEngineEQ.query({
query: "What is the color of the dog?",
});
console.log("Filter with dogId 2 response:", responseEQ.toString());
console.log(
"\n=============\nQuerying index with dogId IN (1, 3). The output should be brown and red.",
);
const queryEngineIN = index.asQueryEngine({
preFilters: {
filters: [
{
key: "dogId",
value: ["1", "3"],
operator: "in",
},
],
},
similarityTopK: 3,
});
const responseIN = await queryEngineIN.query({
query: "What is the color of the dog?",
});
console.log("Filter with dogId IN (1, 3) response:", responseIN.toString());
console.log(
"\n=============\nQuerying index with dogId IN (1, 3). The output should be any.",
);
const queryEngineOR = index.asQueryEngine({
preFilters: {
filters: [
{
key: "private",
value: "false",
operator: "==",
},
{
key: "dogId",
value: ["1", "3"],
operator: "in",
},
],
condition: "or",
},
similarityTopK: 3,
});
const responseOR = await queryEngineOR.query({
query: "What is the color of the dog?",
});
console.log(
"Filter with dogId with OR operator response:",
responseOR.toString(),
);
}
void main();
+2 -2
View File
@@ -25,10 +25,10 @@ Here are two sample scripts which work with loading and querying data from a Mil
This sample loads the same dataset of movie reviews as sample dataset. You can install https://github.com/zilliztech/attu to inspect the loaded data.
run `npx ts-node milvus/load`
run `npx tsx milvus/load`
## Use RAG to Query the data
Check out your data in Attu and change the sample query as you see fit.
run `npx ts-node milvus/query`
run `npx tsx milvus/query`
+11 -35
View File
@@ -28,12 +28,23 @@ async function loadAndIndex() {
"full_text",
]);
const FILTER_METADATA_FIELD = "content_type";
documents.forEach((document, index) => {
const contentType = ["tweet", "post", "story"][index % 3]; // assign a random content type to each document
document.metadata = {
...document.metadata,
[FILTER_METADATA_FIELD]: contentType,
};
});
// create Atlas as a vector store
const vectorStore = new MongoDBAtlasVectorSearch({
mongodbClient: client,
dbName: databaseName,
collectionName: vectorCollectionName, // this is where your embeddings will be stored
indexName: indexName, // this is the name of the index you will need to create
indexedMetadataFields: [FILTER_METADATA_FIELD], // this is the field that will be used for the query
});
// now create an index from all the Documents and store them in Atlas
@@ -45,39 +56,4 @@ async function loadAndIndex() {
await client.close();
}
/**
* This method is document in https://www.mongodb.com/docs/atlas/atlas-search/create-index/#create-an-fts-index-programmatically
* But, while testing a 'CommandNotFound' error occurred, so we're not using this here.
*/
async function createSearchIndex() {
const client = new MongoClient(mongoUri);
const database = client.db(databaseName);
const collection = database.collection(vectorCollectionName);
// define your Atlas Search index
const index = {
name: indexName,
definition: {
/* search index definition fields */
mappings: {
dynamic: true,
fields: [
{
type: "vector",
path: "embedding",
numDimensions: 1536,
similarity: "cosine",
},
],
},
},
};
// run the helper method
const result = await collection.createSearchIndex(index);
console.log("Successfully created search index:", result);
await client.close();
}
loadAndIndex().catch(console.error);
// you can't query your index yet because you need to create a vector search index in mongodb's UI now
+14 -2
View File
@@ -14,14 +14,26 @@ async function query() {
dbName: process.env.MONGODB_DATABASE!,
collectionName: process.env.MONGODB_VECTORS!,
indexName: process.env.MONGODB_VECTOR_INDEX!,
indexedMetadataFields: ["content_type"],
});
const index = await VectorStoreIndex.fromVectorStore(store);
const retriever = index.asRetriever({ similarityTopK: 20 });
const queryEngine = index.asQueryEngine({ retriever });
const queryEngine = index.asQueryEngine({
retriever,
preFilters: {
filters: [
{
key: "content_type",
value: "story", // try "tweet" or "post" to see the difference
operator: "==",
},
],
},
});
const result = await queryEngine.query({
query: "What does the author think of web frameworks?",
query: "What does author receive when he was 11 years old?", // Isaac Asimov's "Foundation" for Christmas
});
console.log(result.response);
await client.close();
+3 -42
View File
@@ -34,7 +34,7 @@ MONGODB_COLLECTION=tiny_tweets_collection
You are now ready to import our ready-made data set into Mongo. This is the file `tinytweets.json`, a selection of approximately 1000 tweets from @seldo on Twitter in mid-2019. With your environment set up you can do this by running
```
npx ts-node mongodb/1_import.ts
npx tsx mongodb/1_import.ts
```
If you don't want to use tweets, you can replace `json_file` with any other array of JSON objects, but you will need to modify some code later to make sure the correct field gets indexed. There is no LlamaIndex-specific code here; you can load your data into Mongo any way you want to.
@@ -59,7 +59,7 @@ MONGODB_VECTOR_INDEX=tiny_tweets_vector_index
If the data you're indexing is the tweets we gave you, you're ready to go:
```bash
npx ts-node mongodb/2_load_and_index.ts
npx tsx mongodb/2_load_and_index.ts
```
> Note: this script is running a couple of minutes and currently doesn't show any progress.
@@ -68,51 +68,12 @@ What you're doing here is creating a Reader which loads the data out of Mongo in
Now you're creating a vector search client for Mongo. In addition to a MongoDB client object, you again tell it what database everything is in. This time you give it the name of the collection where you'll store the vector embeddings, and the name of the vector search index you'll create in the next step.
### Create a vector search index
Now if all has gone well you should be able to log in to the Mongo Atlas UI and see two collections in your database: the original data in `tiny_tweets_collection`, and the vector embeddings in `tiny_tweets_vectors`.
![MongoDB Atlas collections](./docs/3_vectors_in_db.png)
Now it's time to create the vector search index so that you can query the data.
It's not yet possible to programmatically create a vector search index using the [`createIndex`](https://www.mongodb.com/docs/manual/reference/method/db.collection.createIndex/) function, therefore we have to create one manually in the UI.
To do so, first, click the 'Atlas Search' tab, and then click "Create Search Index":
![MongoDB Atlas create search index](./docs/4_search_tab.png)
We have to use the JSON editor, as the Visual Editor does not yet support to create a vector search index:
![MongoDB Atlas JSON editor](./docs/5_json_editor.png)
Now under "database and collection" select `tiny_tweets_db` and within that select `tiny_tweets_vectors`. Then under "Index name" enter `tiny_tweets_vector_index` (or whatever value you put for MONGODB_VECTOR_INDEX in `.env`). Under that, you'll want to enter this JSON object:
```json
{
"fields": [
{
"type": "vector",
"path": "embedding",
"numDimensions": 1536,
"similarity": "cosine"
}
]
}
```
This tells Mongo that the `embedding` field in each document (in the `tiny_tweets_vectors` collection) is a vector of 1536 dimensions (this is the size of embeddings used by OpenAI), and that we want to use cosine similarity to compare vectors. You don't need to worry too much about these values unless you want to use a different LLM to OpenAI entirely.
The UI will ask you to review and confirm your choices, then you need to wait a minute or two while it generates the index. If all goes well, you should see something like this screen:
![MongoDB Atlas index created](./docs/7_index_created.png)
Now you're ready to query your data!
### Run a test query
You can do this by running
```bash
npx ts-node mongodb/3_query.ts
npx tsx mongodb/3_query.ts
```
This sets up a connection to Atlas just like `2_load_and_index.ts` did, then it creates a [query engine](https://docs.llamaindex.ai/en/stable/understanding/querying/querying.html#getting-started) and runs a query against it.
+40
View File
@@ -0,0 +1,40 @@
// call pnpm tsx multimodal/load.ts first to init the storage
import { OpenAI, Settings, SimpleChatEngine, imageToDataUrl } from "llamaindex";
import fs from "node:fs/promises";
import path from "path";
// Update llm
Settings.llm = new OpenAI({ model: "gpt-4o-mini", maxTokens: 512 });
async function main() {
const chatEngine = new SimpleChatEngine();
// Load the image and convert it to a data URL
const imagePath = path.join(__dirname, ".", "data", "60.jpg");
// 1. you can read the buffer from the file
const imageBuffer = await fs.readFile(imagePath);
const dataUrl = await imageToDataUrl(imageBuffer);
// or 2. you can just pass the file path to the imageToDataUrl function
// const dataUrl = await imageToDataUrl(imagePath);
// Update the image_url in the chat message
const response = await chatEngine.chat({
message: [
{
type: "text",
text: "What is in this image?",
},
{
type: "image_url",
image_url: {
url: dataUrl,
},
},
],
});
console.log(response.message.content);
}
main().catch(console.error);
+2 -3
View File
@@ -4,7 +4,6 @@ import {
NodeWithScore,
ObjectType,
OpenAI,
RetrievalEndEvent,
Settings,
VectorStoreIndex,
} from "llamaindex";
@@ -18,8 +17,8 @@ Settings.chunkOverlap = 20;
Settings.llm = new OpenAI({ model: "gpt-4-turbo", maxTokens: 512 });
// Update callbackManager
Settings.callbackManager.on("retrieve-end", (event: RetrievalEndEvent) => {
const { nodes, query } = event.detail.payload;
Settings.callbackManager.on("retrieve-end", (event) => {
const { nodes, query } = event.detail;
const imageNodes = nodes.filter(
(node: NodeWithScore) => node.node.type === ObjectType.IMAGE_DOCUMENT,
);
+83
View File
@@ -0,0 +1,83 @@
import {
ImageDocument,
JinaAIEmbedding,
similarity,
SimilarityType,
SimpleDirectoryReader,
} from "llamaindex";
import path from "path";
async function main() {
const jina = new JinaAIEmbedding({
model: "jina-clip-v1",
});
// Get text embeddings
const text1 = "a car";
const textEmbedding1 = await jina.getTextEmbedding(text1);
const text2 = "a football match";
const textEmbedding2 = await jina.getTextEmbedding(text2);
// Get image embedding
const image =
"https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/football-match.jpg";
const imageEmbedding = await jina.getImageEmbedding(image);
// Calc similarity between text and image
const sim1 = similarity(
textEmbedding1,
imageEmbedding,
SimilarityType.DEFAULT,
);
const sim2 = similarity(
textEmbedding2,
imageEmbedding,
SimilarityType.DEFAULT,
);
console.log(`Similarity between "${text1}" and the image is ${sim1}`);
console.log(`Similarity between "${text2}" and the image is ${sim2}`);
// Get multiple text embeddings
const textEmbeddings = await jina.getTextEmbeddings([text1, text2]);
const sim3 = similarity(
textEmbeddings[0],
textEmbeddings[1],
SimilarityType.DEFAULT,
);
console.log(
`Similarity between the two texts "${text1}" and "${text2}" is ${sim3}`,
);
// Get multiple image embeddings
const catImg1 =
"https://i.pinimg.com/600x315/21/48/7e/21487e8e0970dd366dafaed6ab25d8d8.jpg";
const catImg2 =
"https://i.pinimg.com/736x/c9/f2/3e/c9f23e212529f13f19bad5602d84b78b.jpg";
const imageEmbeddings = await jina.getImageEmbeddings([catImg1, catImg2]);
const sim4 = similarity(
imageEmbeddings[0],
imageEmbeddings[1],
SimilarityType.DEFAULT,
);
console.log(`Similarity between the two online cat images is ${sim4}`);
// Get image embeddings from multiple local files
const documents = await new SimpleDirectoryReader().loadData({
directoryPath: path.join("multimodal", "data"),
});
const localImages = documents
.filter((doc) => doc instanceof ImageDocument)
.slice(0, 2); // Get only the first two images
const localImageEmbeddings = await jina.getImageEmbeddings(
localImages.map((doc) => (doc as ImageDocument).image),
);
const sim5 = similarity(
localImageEmbeddings[0],
localImageEmbeddings[1],
SimilarityType.DEFAULT,
);
console.log(`Similarity between the two local images is ${sim5}`);
}
void main();
+2 -3
View File
@@ -1,7 +1,6 @@
import {
MultiModalResponseSynthesizer,
OpenAI,
RetrievalEndEvent,
Settings,
VectorStoreIndex,
} from "llamaindex";
@@ -15,8 +14,8 @@ Settings.chunkOverlap = 20;
Settings.llm = new OpenAI({ model: "gpt-4-turbo", maxTokens: 512 });
// Update callbackManager
Settings.callbackManager.on("retrieve-end", (event: RetrievalEndEvent) => {
const { nodes, query } = event.detail.payload;
Settings.callbackManager.on("retrieve-end", (event) => {
const { nodes, query } = event.detail;
console.log(`Retrieved ${nodes.length} nodes for query: ${query}`);
});
+13
View File
@@ -0,0 +1,13 @@
import { OpenAI } from "llamaindex";
(async () => {
const llm = new OpenAI({ model: "o1-preview", temperature: 1 });
const prompt = `What are three compounds we should consider investigating to advance research
into new antibiotics? Why should we consider them?
`;
// complete api
const response = await llm.complete({ prompt });
console.log(response.text);
})();
+11 -10
View File
@@ -1,26 +1,27 @@
{
"name": "@llamaindex/examples",
"private": true,
"version": "0.0.6",
"version": "0.0.8",
"dependencies": {
"@aws-crypto/sha256-js": "^5.2.0",
"@datastax/astra-db-ts": "^1.2.1",
"@azure/identity": "^4.4.1",
"@datastax/astra-db-ts": "^1.4.1",
"@llamaindex/core": "^0.2.0",
"@notionhq/client": "^2.2.15",
"@pinecone-database/pinecone": "^2.2.2",
"@zilliz/milvus2-sdk-node": "^2.4.2",
"@pinecone-database/pinecone": "^3.0.2",
"@zilliz/milvus2-sdk-node": "^2.4.6",
"chromadb": "^1.8.1",
"commander": "^12.1.0",
"dotenv": "^16.4.5",
"js-tiktoken": "^1.0.12",
"llamaindex": "^0.4.3",
"js-tiktoken": "^1.0.14",
"llamaindex": "^0.6.0",
"mongodb": "^6.7.0",
"pathe": "^1.1.2"
},
"devDependencies": {
"@types/node": "^20.14.1",
"ts-node": "^10.9.2",
"tsx": "^4.15.6",
"typescript": "^5.5.2"
"@types/node": "^22.5.1",
"tsx": "^4.19.0",
"typescript": "^5.5.4"
},
"scripts": {
"lint": "eslint ."
+2 -2
View File
@@ -37,7 +37,7 @@ Read and follow the instructions in the README.md file located one directory up
To import documents and save the embedding vectors to your database:
> `npx ts-node pg-vector-store/load-docs.ts data`
> `npx tsx pg-vector-store/load-docs.ts data`
where data is the directory containing your input files. Using the `data` directory in the example above will read all of the files in that directory using the LlamaIndexTS default readers for each file type.
@@ -45,6 +45,6 @@ where data is the directory containing your input files. Using the `data` direct
To query using the resulting vector store:
> `npx ts-node pg-vector-store/query.ts`
> `npx tsx pg-vector-store/query.ts`
The script will prompt for a question, then process and present the answer using the PGVectorStore data and your OpenAI API key. It will continue to prompt until you enter `q`, `quit` or `exit` as the next query.
+2 -2
View File
@@ -19,7 +19,7 @@ Read and follow the instructions in the README.md file located one directory up
To import documents and save the embedding vectors to your database:
> `npx ts-node pinecone-vector-store/load-docs.ts data`
> `npx tsx pinecone-vector-store/load-docs.ts data`
where data is the directory containing your input files. Using the _data_ directory in the example above will read all of the files in that directory using the llamaindexTS default readers for each file type.
@@ -29,6 +29,6 @@ where data is the directory containing your input files. Using the _data_ direct
To query using the resulting vector store:
> `npx ts-node pinecone-vector-store/query.ts`
> `npx tsx pinecone-vector-store/query.ts`
The script will prompt for a question, then process and present the answer using the PineconeVectorStore data and your OpenAI API key. It will continue to prompt until you enter `q`, `quit` or `exit` as the next query.
+2 -2
View File
@@ -5,7 +5,7 @@ import {
IngestionPipeline,
MetadataMode,
OpenAIEmbedding,
SimpleNodeParser,
SentenceSplitter,
} from "llamaindex";
async function main() {
@@ -18,7 +18,7 @@ async function main() {
const document = new Document({ text: essay, id_: path });
const pipeline = new IngestionPipeline({
transformations: [
new SimpleNodeParser({ chunkSize: 1024, chunkOverlap: 20 }),
new SentenceSplitter({ chunkSize: 1024, chunkOverlap: 20 }),
new OpenAIEmbedding(),
],
});
+7 -6
View File
@@ -1,21 +1,22 @@
import {
Document,
PromptTemplate,
ResponseSynthesizer,
TreeSummarize,
TreeSummarizePrompt,
VectorStoreIndex,
} from "llamaindex";
const treeSummarizePrompt: TreeSummarizePrompt = ({ context, query }) => {
return `Context information from multiple sources is below.
const treeSummarizePrompt: TreeSummarizePrompt = new PromptTemplate({
template: `Context information from multiple sources is below.
---------------------
${context}
{context}
---------------------
Given the information from multiple sources and not prior knowledge.
Answer the query in the style of a Shakespeare play"
Query: ${query}
Answer:`;
};
Query: {query}
Answer:`,
});
async function main() {
const documents = new Document({
+1 -1
View File
@@ -8,4 +8,4 @@ Add your OpenAI API Key into a file called `.env` in the parent folder of this d
OPEN_API_KEY=sk-you-key
```
Now, open a new terminal window and inside `examples`, run `npx ts-node qdrantdb/preFilters.ts`.
Now, open a new terminal window and inside `examples`, run `npx tsx qdrantdb/preFilters.ts`.
+8 -9
View File
@@ -1,8 +1,8 @@
import * as dotenv from "dotenv";
import {
CallbackManager,
Document,
MetadataMode,
NodeWithScore,
QdrantVectorStore,
Settings,
VectorStoreIndex,
@@ -10,13 +10,12 @@ import {
} from "llamaindex";
// Update callback manager
Settings.callbackManager = new CallbackManager({
onRetrieve: (data) => {
console.log(
"The retrieved nodes are:",
data.nodes.map((node) => node.node.getContent(MetadataMode.NONE)),
);
},
Settings.callbackManager.on("retrieve-end", (event) => {
const { nodes } = event.detail;
console.log(
"The retrieved nodes are:",
nodes.map((node: NodeWithScore) => node.node.getContent(MetadataMode.NONE)),
);
});
// Load environment variables from local .env file
@@ -65,7 +64,7 @@ async function main() {
{
key: "dogId",
value: "2",
filterType: "ExactMatch",
operator: "==",
},
],
},
+7 -4
View File
@@ -11,15 +11,18 @@
"start:pdf": "node --import tsx ./src/pdf.ts",
"start:llamaparse": "node --import tsx ./src/llamaparse.ts",
"start:notion": "node --import tsx ./src/notion.ts",
"start:assemblyai": "node --import tsx ./src/assemblyai.ts",
"start:llamaparse-dir": "node --import tsx ./src/simple-directory-reader-with-llamaparse.ts",
"start:llamaparse-json": "node --import tsx ./src/llamaparse-json.ts"
"start:llamaparse-json": "node --import tsx ./src/llamaparse-json.ts",
"start:discord": "node --import tsx ./src/discord.ts",
"start:json": "node --import tsx ./src/json.ts"
},
"dependencies": {
"llamaindex": "*"
},
"devDependencies": {
"@types/node": "^20.12.11",
"tsx": "^4.15.6",
"typescript": "^5.5.2"
"@types/node": "^22.5.1",
"tsx": "^4.19.0",
"typescript": "^5.5.4"
}
}
+8 -6
View File
@@ -1,6 +1,7 @@
import {
CompactAndRefine,
OpenAI,
PromptTemplate,
ResponseSynthesizer,
Settings,
VectorStoreIndex,
@@ -18,14 +19,15 @@ async function main() {
// Split text and create embeddings. Store them in a VectorStoreIndex
const index = await VectorStoreIndex.fromDocuments(documents);
const csvPrompt = ({ context = "", query = "" }) => {
return `The following CSV file is loaded from ${path}
const csvPrompt = new PromptTemplate({
templateVars: ["query", "context"],
template: `The following CSV file is loaded from ${path}
\`\`\`csv
${context}
{context}
\`\`\`
Given the CSV file, generate me Typescript code to answer the question: ${query}. You can use built in NodeJS functions but avoid using third party libraries.
`;
};
Given the CSV file, generate me Typescript code to answer the question: {query}. You can use built in NodeJS functions but avoid using third party libraries.
`,
});
const responseSynthesizer = new ResponseSynthesizer({
responseBuilder: new CompactAndRefine(undefined, csvPrompt),
+20
View File
@@ -0,0 +1,20 @@
import { DiscordReader } from "llamaindex";
async function main() {
// Create an instance of the DiscordReader. Set token here or DISCORD_TOKEN environment variable
const discordReader = new DiscordReader();
// Specify the channel IDs you want to read messages from as an arry of strings
const channelIds = ["721374320794009630", "719596376261918720"];
// Specify the number of messages to fetch per channel
const limit = 10;
// Load messages from the specified channel
const messages = await discordReader.loadData(channelIds, limit, true);
// Print out the messages
console.log(messages);
}
main().catch(console.error);
+49
View File
@@ -0,0 +1,49 @@
import { JSONReader } from "llamaindex";
async function main() {
// Data
const file = "../data/tinytweets.json";
const nonAsciiContent = '{"message": "こんにちは世界"}';
const jsonlContent = '{"tweet": "Hello world"}\n{"tweet": "こんにちは世界"}';
// Convert strings to Uint8Array for loadDataAsContent
const nonAsciiBuffer = new TextEncoder().encode(nonAsciiContent);
const jsonlBuffer = new TextEncoder().encode(jsonlContent);
// Default settings
const reader1 = new JSONReader();
const docs1 = await reader1.loadData(file);
console.log(docs1[0]);
// Unclean JSON
const reader2 = new JSONReader({ cleanJson: false });
const docs2 = await reader2.loadData(file);
console.log(docs2[0]);
// Depth first yield of JSON structural paths, going back 2 levels
const reader3 = new JSONReader({ levelsBack: 2 });
const docs3 = await reader3.loadData(file);
console.log(docs3[0]);
// Depth first yield of all levels
const reader4 = new JSONReader({ levelsBack: 0 });
const docs4 = await reader4.loadData(file);
console.log(docs4[0]);
// Depth first yield of all levels, collapse structural paths below length 100
const reader5 = new JSONReader({ levelsBack: 0, collapseLength: 100 });
const docs5 = await reader5.loadData(file);
console.log(docs5[0]);
// Convert ASCII to unichode escape sequences
const reader6 = new JSONReader({ ensureAscii: true });
const docs6 = await reader6.loadDataAsContent(nonAsciiBuffer);
console.log(docs6[0]);
// JSON Lines Format
const reader7 = new JSONReader({ isJsonLines: true });
const docs7 = await reader7.loadDataAsContent(jsonlBuffer);
console.log(docs7[0]);
}
main().catch(console.error);
+4 -1
View File
@@ -3,6 +3,7 @@ import {
ImageNode,
LlamaParseReader,
OpenAI,
PromptTemplate,
VectorStoreIndex,
} from "llamaindex";
import { createMessageContent } from "llamaindex/synthesizers/utils";
@@ -50,7 +51,9 @@ async function getImageTextDocs(
for (const imageDict of imageDicts) {
const imageDoc = new ImageNode({ image: imageDict.path });
const prompt = () => `Describe the image as alt text`;
const prompt = new PromptTemplate({
template: `Describe the image as alt text`,
});
const message = await createMessageContent(prompt, [imageDoc]);
const response = await llm.complete({
+5 -5
View File
@@ -1,7 +1,7 @@
import { extractText } from "@llamaindex/core/utils";
import { encodingForModel } from "js-tiktoken";
import { ChatMessage, OpenAI, type LLMStartEvent } from "llamaindex";
import { ChatMessage, OpenAI } from "llamaindex";
import { Settings } from "llamaindex/Settings";
import { extractText } from "llamaindex/llm/utils";
const encoding = encodingForModel("gpt-4-0125-preview");
@@ -12,8 +12,8 @@ const llm = new OpenAI({
let tokenCount = 0;
Settings.callbackManager.on("llm-start", (event: LLMStartEvent) => {
const { messages } = event.detail.payload;
Settings.callbackManager.on("llm-start", (event) => {
const { messages } = event.detail;
messages.reduce((count: number, message: ChatMessage) => {
return count + encoding.encode(extractText(message.content)).length;
}, 0);
@@ -24,7 +24,7 @@ Settings.callbackManager.on("llm-start", (event: LLMStartEvent) => {
});
Settings.callbackManager.on("llm-stream", (event) => {
const { chunk } = event.detail.payload;
const { chunk } = event.detail;
const { delta } = chunk;
tokenCount += encoding.encode(extractText(delta)).length;
if (tokenCount > 20) {
+3 -3
View File
@@ -15,9 +15,9 @@ async function main() {
const index = await VectorStoreIndex.fromDocuments([document]);
const retriever = index.asRetriever();
retriever.similarityTopK = 5;
const retriever = index.asRetriever({
similarityTopK: 5,
});
const nodePostprocessor = new CohereRerank({
apiKey: "<COHERE_API_KEY>",
+2 -2
View File
@@ -1,9 +1,9 @@
import {
OpenAI,
RouterQueryEngine,
SentenceSplitter,
Settings,
SimpleDirectoryReader,
SimpleNodeParser,
SummaryIndex,
VectorStoreIndex,
} from "llamaindex";
@@ -12,7 +12,7 @@ import {
Settings.llm = new OpenAI();
// Update node parser
Settings.nodeParser = new SimpleNodeParser({
Settings.nodeParser = new SentenceSplitter({
chunkSize: 1024,
});
+1 -1
View File
@@ -8,7 +8,7 @@ async function main() {
const textSplitter = new SentenceSplitter();
const chunks = textSplitter.splitTextWithOverlaps(essay);
const chunks = textSplitter.splitText(essay);
console.log(chunks);
}
+2 -2
View File
@@ -1,7 +1,7 @@
import {
Document,
SentenceSplitter,
Settings,
SimpleNodeParser,
SummaryIndex,
SummaryRetrieverMode,
} from "llamaindex";
@@ -9,7 +9,7 @@ import {
import essay from "./essay";
// Update node parser
Settings.nodeParser = new SimpleNodeParser({
Settings.nodeParser = new SentenceSplitter({
chunkSize: 40,
});
-2
View File
@@ -7,8 +7,6 @@
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"lib": ["ES2022"],
"types": ["node"],
"outDir": "./lib",
"tsBuildInfoFile": "./lib/.tsbuildinfo",
"incremental": true,
+3 -2
View File
@@ -18,8 +18,9 @@ async function main() {
const index = await VectorStoreIndex.fromDocuments([document]);
const retriever = index.asRetriever();
retriever.similarityTopK = 5;
const retriever = index.asRetriever({
similarityTopK: 5,
});
const nodePostprocessor = new SimilarityPostprocessor({
similarityCutoff: 0.7,
});
+31
View File
@@ -0,0 +1,31 @@
# Weaviate Vector Store
Here are two sample scripts which work with loading and querying data from a Weaviate Vector Store.
## Prerequisites
- An Weaviate Vector Database
- Hosted https://weaviate.io/
- Self Hosted https://weaviate.io/developers/weaviate/installation/docker-compose#starter-docker-compose-file
- An OpenAI API Key
## Setup
1. Set your env variables:
- `WEAVIATE_CLUSTER_URL`: Address of your Weaviate Vector Store (like localhost:8080)
- `WEAVIATE_API_KEY`: Your Weaviate API key
- `OPENAI_API_KEY`: Your OpenAI key
2. `cd` Into the `examples` directory
3. run `npm i`
## Load the data
This sample loads the same dataset of movie reviews as sample dataset
run `npx tsx weaviate/load`
## Use RAG to Query the data
run `npx tsx weaviate/query`
+23
View File
@@ -0,0 +1,23 @@
import {
PapaCSVReader,
storageContextFromDefaults,
VectorStoreIndex,
WeaviateVectorStore,
} from "llamaindex";
const indexName = "MovieReviews";
async function main() {
try {
const reader = new PapaCSVReader(false);
const docs = await reader.loadData("./data/movie_reviews.csv");
const vectorStore = new WeaviateVectorStore({ indexName });
const storageContext = await storageContextFromDefaults({ vectorStore });
await VectorStoreIndex.fromDocuments(docs, { storageContext });
console.log("Successfully loaded data into Weaviate");
} catch (e) {
console.error(e);
}
}
void main();
+46
View File
@@ -0,0 +1,46 @@
import { VectorStoreIndex, WeaviateVectorStore } from "llamaindex";
const indexName = "MovieReviews";
async function main() {
try {
const query = "Get all movie titles.";
const vectorStore = new WeaviateVectorStore({ indexName });
const index = await VectorStoreIndex.fromVectorStore(vectorStore);
const retriever = index.asRetriever({ similarityTopK: 20 });
const queryEngine = index.asQueryEngine({ retriever });
const results = await queryEngine.query({ query });
console.log(`Query from ${results.sourceNodes?.length} nodes`);
console.log(results.response);
console.log("\n=====\nQuerying the index with filters");
const queryEngineWithFilters = index.asQueryEngine({
retriever,
preFilters: {
filters: [
{
key: "document_id",
value: "./data/movie_reviews.csv_37",
operator: "==",
},
{
key: "document_id",
value: "./data/movie_reviews.csv_21",
operator: "==",
},
],
condition: "or",
},
});
const resultAfterFilter = await queryEngineWithFilters.query({
query: "Get all movie titles.",
});
console.log(`Query from ${resultAfterFilter.sourceNodes?.length} nodes`);
console.log(resultAfterFilter.response);
} catch (e) {
console.error(e);
}
}
void main();
+7
View File
@@ -0,0 +1,7 @@
# Workflow Examples
These examples demonstrate LlamaIndexTS's workflow system. Check out [its documentation](https://ts.llamaindex.ai/modules/workflows) for more information.
## Running the Examples
To run the examples, make sure to run them from the parent folder called `examples`). For example, to run the joke workflow, run `npx tsx workflow/joke.ts`.
+122
View File
@@ -0,0 +1,122 @@
import {
Context,
StartEvent,
StopEvent,
Workflow,
WorkflowEvent,
} from "@llamaindex/core/workflow";
import { OpenAI } from "llamaindex";
const MAX_REVIEWS = 3;
// Using the o1-preview model (see https://platform.openai.com/docs/guides/reasoning?reasoning-prompt-examples=coding-planning)
const llm = new OpenAI({ model: "o1-preview", temperature: 1 });
// example specification from https://platform.openai.com/docs/guides/reasoning?reasoning-prompt-examples=coding-planning
const specification = `Python app that takes user questions and looks them up in a
database where they are mapped to answers. If there is a close match, it retrieves
the matched answer. If there isn't, it asks the user to provide an answer and
stores the question/answer pair in the database.`;
// Create custom event types
export class MessageEvent extends WorkflowEvent<{ msg: string }> {}
export class CodeEvent extends WorkflowEvent<{ code: string }> {}
export class ReviewEvent extends WorkflowEvent<{
review: string;
code: string;
}> {}
// Helper function to truncate long strings
const truncate = (str: string) => {
const MAX_LENGTH = 60;
if (str.length <= MAX_LENGTH) return str;
return str.slice(0, MAX_LENGTH) + "...";
};
// the architect is responsible for writing the structure and the initial code based on the specification
const architect = async (context: Context, ev: StartEvent) => {
// get the specification from the start event and save it to context
context.set("specification", ev.data.input);
const spec = context.get("specification");
// write a message to send an update to the user
context.writeEventToStream(
new MessageEvent({
msg: `Writing app using this specification: ${truncate(spec)}`,
}),
);
const prompt = `Build an app for this specification: <spec>${spec}</spec>. Make a plan for the directory structure you'll need, then return each file in full. Don't supply any reasoning, just code.`;
const code = await llm.complete({ prompt });
return new CodeEvent({ code: code.text });
};
// the coder is responsible for updating the code based on the review
const coder = async (context: Context, ev: ReviewEvent) => {
// get the specification from the context
const spec = context.get("specification");
// get the latest review and code
const { review, code } = ev.data;
// write a message to send an update to the user
context.writeEventToStream(
new MessageEvent({
msg: `Update code based on review: ${truncate(review)}`,
}),
);
const prompt = `We need to improve code that should implement this specification: <spec>${spec}</spec>. Here is the current code: <code>${code}</code>. And here is a review of the code: <review>${review}</review>. Improve the code based on the review, keep the specification in mind, and return the full updated code. Don't supply any reasoning, just code.`;
const updatedCode = await llm.complete({ prompt });
return new CodeEvent({ code: updatedCode.text });
};
// the reviewer is responsible for reviewing the code and providing feedback
const reviewer = async (context: Context, ev: CodeEvent) => {
// get the specification from the context
const spec = context.get("specification");
// get latest code from the event
const { code } = ev.data;
// update and check the number of reviews
const numberReviews = context.get("numberReviews", 0) + 1;
context.set("numberReviews", numberReviews);
if (numberReviews > MAX_REVIEWS) {
// the we've done this too many times - return the code
context.writeEventToStream(
new MessageEvent({
msg: `Already reviewed ${numberReviews - 1} times, stopping!`,
}),
);
return new StopEvent({ result: code });
}
// write a message to send an update to the user
context.writeEventToStream(
new MessageEvent({ msg: `Review #${numberReviews}: ${truncate(code)}` }),
);
const prompt = `Review this code: <code>${code}</code>. Check if the code quality and whether it correctly implements this specification: <spec>${spec}</spec>. If you're satisfied, just return 'Looks great', nothing else. If not, return a review with a list of changes you'd like to see.`;
const review = (await llm.complete({ prompt })).text;
if (review.includes("Looks great")) {
// the reviewer is satisfied with the code, let's return the review
context.writeEventToStream(
new MessageEvent({
msg: `Reviewer says: ${review}`,
}),
);
return new StopEvent({ result: code });
}
return new ReviewEvent({ review, code });
};
const codeAgent = new Workflow({ validate: true });
codeAgent.addStep(StartEvent, architect, { outputs: CodeEvent });
codeAgent.addStep(ReviewEvent, coder, { outputs: CodeEvent });
codeAgent.addStep(CodeEvent, reviewer, { outputs: ReviewEvent });
// Usage
async function main() {
const run = codeAgent.run(specification);
for await (const event of codeAgent.streamEvents()) {
const msg = (event as MessageEvent).data.msg;
console.log(`${msg}\n`);
}
const result = await run;
console.log("Final code:\n", result.data.result);
}
main().catch(console.error);
+70
View File
@@ -0,0 +1,70 @@
import {
Context,
StartEvent,
StopEvent,
Workflow,
WorkflowEvent,
} from "@llamaindex/core/workflow";
import { OpenAI } from "llamaindex";
// Create LLM instance
const llm = new OpenAI();
// Create custom event types
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
export class CritiqueEvent extends WorkflowEvent<{ critique: string }> {}
export class AnalysisEvent extends WorkflowEvent<{ analysis: string }> {}
const generateJoke = async (_context: Context, ev: StartEvent) => {
const prompt = `Write your best joke about ${ev.data.input}.`;
const response = await llm.complete({ prompt });
return new JokeEvent({ joke: response.text });
};
const critiqueJoke = async (_context: Context, ev: JokeEvent) => {
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
const response = await llm.complete({ prompt });
return new CritiqueEvent({ critique: response.text });
};
const analyzeJoke = async (_context: Context, ev: JokeEvent) => {
const prompt = `Give a thorough analysis of the following joke: ${ev.data.joke}`;
const response = await llm.complete({ prompt });
return new AnalysisEvent({ analysis: response.text });
};
const reportJoke = async (
context: Context,
ev: AnalysisEvent | CritiqueEvent,
) => {
const events = context.collectEvents(ev, [AnalysisEvent, CritiqueEvent]);
if (!events) {
return;
}
const subPrompts = events.map((event) => {
if (event instanceof AnalysisEvent) {
return `Analysis: ${event.data.analysis}`;
} else if (event instanceof CritiqueEvent) {
return `Critique: ${event.data.critique}`;
}
return "";
});
const prompt = `Based on the following information about a joke:\n${subPrompts.join("\n")}\nProvide a comprehensive report on the joke's quality and impact.`;
const response = await llm.complete({ prompt });
return new StopEvent({ result: response.text });
};
const jokeFlow = new Workflow();
jokeFlow.addStep(StartEvent, generateJoke);
jokeFlow.addStep(JokeEvent, critiqueJoke);
jokeFlow.addStep(JokeEvent, analyzeJoke);
jokeFlow.addStep([AnalysisEvent, CritiqueEvent], reportJoke);
// Usage
async function main() {
const result = await jokeFlow.run("pirates");
console.log(result.data.result);
}
main().catch(console.error);
+38
View File
@@ -0,0 +1,38 @@
import {
Context,
StartEvent,
StopEvent,
Workflow,
WorkflowEvent,
} from "@llamaindex/core/workflow";
import { OpenAI } from "llamaindex";
// Create LLM instance
const llm = new OpenAI();
// Create a custom event type
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
const generateJoke = async (_context: Context, ev: StartEvent) => {
const prompt = `Write your best joke about ${ev.data.input}.`;
const response = await llm.complete({ prompt });
return new JokeEvent({ joke: response.text });
};
const critiqueJoke = async (_context: Context, ev: JokeEvent) => {
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
const response = await llm.complete({ prompt });
return new StopEvent({ result: response.text });
};
const jokeFlow = new Workflow({ verbose: true });
jokeFlow.addStep(StartEvent, generateJoke);
jokeFlow.addStep(JokeEvent, critiqueJoke);
// Usage
async function main() {
const result = await jokeFlow.run("pirates");
console.log(result.data.result);
}
main().catch(console.error);
+49
View File
@@ -0,0 +1,49 @@
import {
Context,
StartEvent,
StopEvent,
Workflow,
WorkflowEvent,
} from "@llamaindex/core/workflow";
import { OpenAI } from "llamaindex";
// Create LLM instance
const llm = new OpenAI();
// Create custom event types
export class JokeEvent extends WorkflowEvent<{ joke: string }> {}
export class MessageEvent extends WorkflowEvent<{ msg: string }> {}
const generateJoke = async (context: Context, ev: StartEvent) => {
context.writeEventToStream(
new MessageEvent({ msg: `Generating a joke about: ${ev.data.input}` }),
);
const prompt = `Write your best joke about ${ev.data.input}.`;
const response = await llm.complete({ prompt });
return new JokeEvent({ joke: response.text });
};
const critiqueJoke = async (context: Context, ev: JokeEvent) => {
context.writeEventToStream(
new MessageEvent({ msg: `Write a critique of this joke: ${ev.data.joke}` }),
);
const prompt = `Give a thorough critique of the following joke: ${ev.data.joke}`;
const response = await llm.complete({ prompt });
return new StopEvent({ result: response.text });
};
const jokeFlow = new Workflow();
jokeFlow.addStep(StartEvent, generateJoke);
jokeFlow.addStep(JokeEvent, critiqueJoke);
// Usage
async function main() {
const run = jokeFlow.run("pirates");
for await (const event of jokeFlow.streamEvents()) {
console.log((event as MessageEvent).data.msg);
}
const result = await run;
console.log(result.data.result);
}
main().catch(console.error);
+37
View File
@@ -0,0 +1,37 @@
import {
Context,
StartEvent,
StopEvent,
Workflow,
} from "@llamaindex/core/workflow";
const longRunning = async (_context: Context, ev: StartEvent) => {
await new Promise((resolve) => setTimeout(resolve, 2000)); // Wait for 2 seconds
return new StopEvent({ result: "We waited 2 seconds" });
};
async function timeout() {
const workflow = new Workflow({ verbose: true, timeout: 1 });
workflow.addStep(StartEvent, longRunning);
// This will timeout
try {
await workflow.run("Let's start");
} catch (error) {
console.error(error);
}
}
async function notimeout() {
// Increase timeout to 3 seconds - no timeout
const workflow = new Workflow({ verbose: true, timeout: 3 });
workflow.addStep(StartEvent, longRunning);
const result = await workflow.run("Let's start");
console.log(result.data.result);
}
async function main() {
await timeout();
await notimeout();
}
main().catch(console.error);

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