Compare commits

..

1 Commits

Author SHA1 Message Date
George He defb9e3ecb Surface parse errors 2025-08-26 12:16:31 -07:00
28 changed files with 2397 additions and 3898 deletions
+2
View File
@@ -19,6 +19,8 @@ jobs:
uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
@@ -1,4 +1,4 @@
name: Lint
name: Lint - Python
on:
push:
@@ -29,18 +29,7 @@ jobs:
- name: Set up Python
run: uv python install ${{ matrix.python-version }}
- uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: "ts/llama_cloud_services/.nvmrc"
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Run linter
shell: bash
working-directory: py
run: uv run -- pre-commit run -a
# the js checks are run roundaboutly through lint-staged, and -a doesn't run it. Run them directly.
- run: pnpm -w --filter llama-cloud-services run lint
- run: pnpm -w --filter llama-cloud-services run format:check
+37
View File
@@ -0,0 +1,37 @@
name: Lint - TypeScript
on:
push:
branches:
- main
paths:
- "ts/**"
pull_request:
paths:
- "ts/**"
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_REMOTE_ONLY: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: "ts/llama_cloud_services/.nvmrc"
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Run lint
working-directory: ts/llama_cloud_services/
run: pnpm run lint
- name: Run Prettier
working-directory: ts/llama_cloud_services/
run: pnpm run format
+4 -2
View File
@@ -13,6 +13,8 @@ jobs:
uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
@@ -47,6 +49,6 @@ jobs:
uses: ncipollo/release-action@v1
with:
artifacts: "ts/llama_cloud_services/llama-cloud-services*.tgz"
name: Release ${{ github.ref_name }} - LlamaCloud Services TS
generateReleaseNotes: true
name: Release ${{ github.ref }} - LlamaCloud Services TS
bodyFile: "ts/llama_cloud_services/CHANGELOG.md"
token: ${{ secrets.GITHUB_TOKEN }}
+7 -4
View File
@@ -1,4 +1,4 @@
name: Test - TypeScript
name: Lint - TypeScript
on:
push:
@@ -23,14 +23,17 @@ jobs:
steps:
- uses: actions/checkout@v5
- uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: "ts/llama_cloud_services/.nvmrc"
- name: Install dependencies
run: pnpm -r install --no-frozen-lockfile
- name: Build package
run: pnpm --filter llama-cloud-services build
run: pnpm install --no-frozen-lockfile
- name: Run Build
working-directory: ts/llama_cloud_services/
run: pnpm build
- name: Run Tests
working-directory: ts/llama_cloud_services/
run: pnpm test
+4 -6
View File
@@ -60,13 +60,11 @@ repos:
additional_dependencies: [black==23.10.1]
# Using PEP 8's line length in docs prevents excess left/right scrolling
args: [--line-length=79]
- repo: local
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.3
hooks:
- id: lint-staged
name: Run lint-staged for TS files
entry: pnpm -w exec lint-staged
language: system
pass_filenames: false
- id: prettier
exclude: ^(uv.lock|ts/llama_cloud_services/pnpm-lock.yaml|ts/e2e-tests)
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
+1 -1
View File
@@ -18,7 +18,7 @@ versions need to be kept consistent to sidecar it with `llama_cloud_services`. B
You can also do this with `./scripts/version-bump.py set 0.x.x` if you have `uv` installed.
Once the change is merged, push a tag `git tag -a v0.x.x -m 0.x.x` and `git push origin v0.x.x`.
Once the change is merged, push a tag `git tag -a v0.x.x -m 0.x.x` and `git push origin 0.x.x`.
This tagging step can be done with `./scripts/version-bump tag`.
-1
View File
@@ -5,6 +5,5 @@ In this folder you will find several python notebooks that contain examples rega
- [LlamaParse](./parse/)
- [LlamaExtract](./extract/)
- [LlamaReport](./report/)
- [LlamaCloudIndex](./index/)
Follow the instructions in each notebook to get started!
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -43,7 +43,7 @@
"source": [
"from llama_cloud_services import LlamaParse\n",
"\n",
"api_key = \"llx-...\" # get from cloud.llamaindex.ai"
"api_key = \"llx-jwAQZL8T38onyL9hKBOXyRtnuCU0Fk3z7tmDhIT3L0GEfohJ\" # get from cloud.llamaindex.ai"
]
},
{
+1
View File
@@ -75,6 +75,7 @@
" adaptive_long_table=True,\n",
" outlined_table_extraction=True,\n",
" output_tables_as_HTML=True,\n",
" api_key=\"llx-jwAQZL8T38onyL9hKBOXyRtnuCU0Fk3z7tmDhIT3L0GEfohJ\",\n",
")\n",
"\n",
"result = await parser.aparse(\"./dcf_template.xlsx\")\n",
-19
View File
@@ -1,19 +0,0 @@
{
"name": "llama-cloud-services-workspace",
"version": "0.0.1",
"description": "",
"private": true,
"keywords": [],
"author": "",
"devDependencies": {
"prettier": "^3.6.2",
"lint-staged": "^15.4.2"
},
"lint-staged": {
"ts/llama_cloud_services/src/**/*.{ts,tsx,js,jsx}": [
"pnpm --filter llama-cloud-services exec eslint --fix",
"pnpm --filter llama-cloud-services exec prettier --write"
]
},
"packageManager": "pnpm@10.11.1+sha512.e519b9f7639869dc8d5c3c5dfef73b3f091094b0a006d7317353c72b124e80e1afd429732e28705ad6bfa1ee879c1fce46c128ccebd3192101f43dd67c667912"
}
-245
View File
@@ -6,15 +6,6 @@ settings:
importers:
.:
devDependencies:
lint-staged:
specifier: ^15.4.2
version: 15.5.2
prettier:
specifier: ^3.6.2
version: 3.6.2
ts/e2e-tests:
devDependencies:
'@types/node':
@@ -838,10 +829,6 @@ packages:
ajv@8.17.1:
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
ansi-escapes@7.0.0:
resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==}
engines: {node: '>=18'}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@@ -946,10 +933,6 @@ packages:
resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
engines: {node: '>=6'}
cli-truncate@4.0.0:
resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
engines: {node: '>=18'}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -961,17 +944,10 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
commander@13.0.0:
resolution: {integrity: sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==}
engines: {node: '>=18'}
commander@13.1.0:
resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==}
engines: {node: '>=18'}
commondir@1.0.1:
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
@@ -1031,10 +1007,6 @@ packages:
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
environment@1.1.0:
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
engines: {node: '>=18'}
es-module-lexer@1.7.0:
resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
@@ -1099,13 +1071,6 @@ packages:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
eventemitter3@5.0.1:
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
execa@8.0.1:
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
engines: {node: '>=16.17'}
expect-type@1.2.2:
resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==}
engines: {node: '>=12.0.0'}
@@ -1187,14 +1152,6 @@ packages:
resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==}
engines: {node: '>=18'}
get-east-asian-width@1.3.1:
resolution: {integrity: sha512-R1QfovbPsKmosqTnPoRFiJ7CF9MLRgb53ChvMZm+r4p76/+8yKDy17qLL2PKInORy2RkZZekuK0efYgmzTkXyQ==}
engines: {node: '>=18'}
get-stream@8.0.1:
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
engines: {node: '>=16'}
get-tsconfig@4.10.1:
resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==}
@@ -1241,10 +1198,6 @@ packages:
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
human-signals@5.0.0:
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
engines: {node: '>=16.17.0'}
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
@@ -1276,14 +1229,6 @@ packages:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-fullwidth-code-point@4.0.0:
resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
engines: {node: '>=12'}
is-fullwidth-code-point@5.1.0:
resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==}
engines: {node: '>=18'}
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
@@ -1306,10 +1251,6 @@ packages:
is-reference@1.2.1:
resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
is-stream@3.0.0:
resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
is-unicode-supported@1.3.0:
resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
engines: {node: '>=12'}
@@ -1373,19 +1314,6 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
lilconfig@3.1.3:
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
engines: {node: '>=14'}
lint-staged@15.5.2:
resolution: {integrity: sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==}
engines: {node: '>=18.12.0'}
hasBin: true
listr2@8.3.3:
resolution: {integrity: sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==}
engines: {node: '>=18.0.0'}
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
@@ -1400,10 +1328,6 @@ packages:
resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==}
engines: {node: '>=18'}
log-update@6.1.0:
resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
engines: {node: '>=18'}
loupe@3.2.0:
resolution: {integrity: sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==}
@@ -1423,9 +1347,6 @@ packages:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -1434,10 +1355,6 @@ packages:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
mimic-fn@4.0.0:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
mimic-function@5.0.1:
resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
engines: {node: '>=18'}
@@ -1497,10 +1414,6 @@ packages:
node-fetch-native@1.6.7:
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
npm-run-path@5.3.0:
resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
nypm@0.5.4:
resolution: {integrity: sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==}
engines: {node: ^14.16.0 || >=16.10.0}
@@ -1509,10 +1422,6 @@ packages:
ohash@1.1.6:
resolution: {integrity: sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==}
onetime@6.0.0:
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
engines: {node: '>=12'}
onetime@7.0.0:
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
engines: {node: '>=18'}
@@ -1552,10 +1461,6 @@ packages:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
path-key@4.0.0:
resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
engines: {node: '>=12'}
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
@@ -1587,11 +1492,6 @@ packages:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
pidtree@0.6.0:
resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==}
engines: {node: '>=0.10'}
hasBin: true
pkg-types@1.3.1:
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
@@ -1658,9 +1558,6 @@ packages:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
rollup-plugin-dts@6.2.1:
resolution: {integrity: sha512-sR3CxYUl7i2CHa0O7bA45mCrgADyAQ0tVtGSqi3yvH28M+eg1+g5d7kQ9hLvEz5dorK3XVsH5L2jwHLQf72DzA==}
engines: {node: '>=16'}
@@ -1712,14 +1609,6 @@ packages:
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
engines: {node: '>=18'}
slice-ansi@5.0.0:
resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
engines: {node: '>=12'}
slice-ansi@7.1.0:
resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
engines: {node: '>=18'}
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@@ -1738,10 +1627,6 @@ packages:
resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==}
engines: {node: '>=18'}
string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@@ -1762,10 +1647,6 @@ packages:
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
engines: {node: '>=12'}
strip-final-newline@3.0.0:
resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
engines: {node: '>=12'}
strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
@@ -1990,10 +1871,6 @@ packages:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
wrap-ansi@9.0.0:
resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
engines: {node: '>=18'}
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@@ -2001,11 +1878,6 @@ packages:
yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
yaml@2.8.1:
resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==}
engines: {node: '>= 14.6'}
hasBin: true
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
@@ -2679,10 +2551,6 @@ snapshots:
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
ansi-escapes@7.0.0:
dependencies:
environment: 1.1.0
ansi-regex@5.0.1: {}
ansi-regex@6.1.0: {}
@@ -2797,11 +2665,6 @@ snapshots:
cli-spinners@2.9.2: {}
cli-truncate@4.0.0:
dependencies:
slice-ansi: 5.0.0
string-width: 7.2.0
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@@ -2814,12 +2677,8 @@ snapshots:
color-name@1.1.4: {}
colorette@2.0.20: {}
commander@13.0.0: {}
commander@13.1.0: {}
commondir@1.0.1: {}
concat-map@0.0.1: {}
@@ -2858,8 +2717,6 @@ snapshots:
emoji-regex@9.2.2: {}
environment@1.1.0: {}
es-module-lexer@1.7.0: {}
esbuild@0.21.5:
@@ -2967,20 +2824,6 @@ snapshots:
esutils@2.0.3: {}
eventemitter3@5.0.1: {}
execa@8.0.1:
dependencies:
cross-spawn: 7.0.6
get-stream: 8.0.1
human-signals: 5.0.0
is-stream: 3.0.0
merge-stream: 2.0.0
npm-run-path: 5.3.0
onetime: 6.0.0
signal-exit: 4.1.0
strip-final-newline: 3.0.0
expect-type@1.2.2: {}
fast-deep-equal@3.1.3: {}
@@ -3056,10 +2899,6 @@ snapshots:
get-east-asian-width@1.3.0: {}
get-east-asian-width@1.3.1: {}
get-stream@8.0.1: {}
get-tsconfig@4.10.1:
dependencies:
resolve-pkg-maps: 1.0.0
@@ -3114,8 +2953,6 @@ snapshots:
html-escaper@2.0.2: {}
human-signals@5.0.0: {}
ieee754@1.2.1: {}
ignore@5.3.2: {}
@@ -3137,12 +2974,6 @@ snapshots:
is-fullwidth-code-point@3.0.0: {}
is-fullwidth-code-point@4.0.0: {}
is-fullwidth-code-point@5.1.0:
dependencies:
get-east-asian-width: 1.3.1
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
@@ -3159,8 +2990,6 @@ snapshots:
dependencies:
'@types/estree': 1.0.8
is-stream@3.0.0: {}
is-unicode-supported@1.3.0: {}
is-unicode-supported@2.1.0: {}
@@ -3224,32 +3053,6 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
lilconfig@3.1.3: {}
lint-staged@15.5.2:
dependencies:
chalk: 5.5.0
commander: 13.1.0
debug: 4.4.1
execa: 8.0.1
lilconfig: 3.1.3
listr2: 8.3.3
micromatch: 4.0.8
pidtree: 0.6.0
string-argv: 0.3.2
yaml: 2.8.1
transitivePeerDependencies:
- supports-color
listr2@8.3.3:
dependencies:
cli-truncate: 4.0.0
colorette: 2.0.20
eventemitter3: 5.0.1
log-update: 6.1.0
rfdc: 1.4.1
wrap-ansi: 9.0.0
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
@@ -3263,14 +3066,6 @@ snapshots:
chalk: 5.5.0
is-unicode-supported: 1.3.0
log-update@6.1.0:
dependencies:
ansi-escapes: 7.0.0
cli-cursor: 5.0.0
slice-ansi: 7.1.0
strip-ansi: 7.1.0
wrap-ansi: 9.0.0
loupe@3.2.0: {}
lru-cache@10.4.3: {}
@@ -3291,8 +3086,6 @@ snapshots:
dependencies:
semver: 7.7.2
merge-stream@2.0.0: {}
merge2@1.4.1: {}
micromatch@4.0.8:
@@ -3300,8 +3093,6 @@ snapshots:
braces: 3.0.3
picomatch: 2.3.1
mimic-fn@4.0.0: {}
mimic-function@5.0.1: {}
minimatch@3.1.2:
@@ -3348,10 +3139,6 @@ snapshots:
node-fetch-native@1.6.7: {}
npm-run-path@5.3.0:
dependencies:
path-key: 4.0.0
nypm@0.5.4:
dependencies:
citty: 0.1.6
@@ -3363,10 +3150,6 @@ snapshots:
ohash@1.1.6: {}
onetime@6.0.0:
dependencies:
mimic-fn: 4.0.0
onetime@7.0.0:
dependencies:
mimic-function: 5.0.1
@@ -3416,8 +3199,6 @@ snapshots:
path-key@3.1.1: {}
path-key@4.0.0: {}
path-parse@1.0.7: {}
path-scurry@1.11.1:
@@ -3439,8 +3220,6 @@ snapshots:
picomatch@4.0.3: {}
pidtree@0.6.0: {}
pkg-types@1.3.1:
dependencies:
confbox: 0.1.8
@@ -3493,8 +3272,6 @@ snapshots:
reusify@1.1.0: {}
rfdc@1.4.1: {}
rollup-plugin-dts@6.2.1(rollup@4.46.2)(typescript@5.9.2):
dependencies:
magic-string: 0.30.17
@@ -3565,16 +3342,6 @@ snapshots:
mrmime: 2.0.1
totalist: 3.0.1
slice-ansi@5.0.0:
dependencies:
ansi-styles: 6.2.1
is-fullwidth-code-point: 4.0.0
slice-ansi@7.1.0:
dependencies:
ansi-styles: 6.2.1
is-fullwidth-code-point: 5.1.0
source-map-js@1.2.1: {}
source-map@0.6.1: {}
@@ -3585,8 +3352,6 @@ snapshots:
stdin-discarder@0.2.2: {}
string-argv@0.3.2: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
@@ -3613,8 +3378,6 @@ snapshots:
dependencies:
ansi-regex: 6.1.0
strip-final-newline@3.0.0: {}
strip-json-comments@3.1.1: {}
strtok3@10.3.4:
@@ -3821,18 +3584,10 @@ snapshots:
string-width: 5.1.2
strip-ansi: 7.1.0
wrap-ansi@9.0.0:
dependencies:
ansi-styles: 6.2.1
string-width: 7.2.0
strip-ansi: 7.1.0
y18n@5.0.8: {}
yallist@4.0.0: {}
yaml@2.8.1: {}
yargs-parser@21.1.1: {}
yargs@17.7.2:
+1 -2
View File
@@ -1,6 +1,6 @@
from llama_cloud_services.parse import LlamaParse
from llama_cloud_services.report import ReportClient, LlamaReport
from llama_cloud_services.extract import LlamaExtract, ExtractionAgent, SourceText
from llama_cloud_services.extract import LlamaExtract, ExtractionAgent
from llama_cloud_services.constants import EU_BASE_URL
from llama_cloud_services.index import (
LlamaCloudCompositeRetriever,
@@ -14,7 +14,6 @@ __all__ = [
"LlamaReport",
"LlamaExtract",
"ExtractionAgent",
"SourceText",
"EU_BASE_URL",
"LlamaCloudIndex",
"LlamaCloudRetriever",
@@ -17,9 +17,6 @@ from llama_cloud_services.files.client import FileClient
from llama_cloud_services.constants import POLLING_TIMEOUT_SECONDS
from llama_cloud_services.utils import is_terminal_status, augment_async_errors
from llama_index.core.async_utils import DEFAULT_NUM_WORKERS, run_jobs
from llama_cloud_services.beta.classifier.types import (
ClassifyJobResultsWithFiles,
)
class ClassificationOutput(BaseModel):
@@ -55,24 +52,6 @@ class ClassifyClient:
self.file_client = FileClient(client, project_id, organization_id)
self.polling_timeout = polling_timeout
@classmethod
def from_api_key(
cls,
api_key: str,
project_id: Optional[str] = None,
organization_id: Optional[str] = None,
base_url: Optional[str] = None,
) -> "ClassifyClient":
"""
Create a classify client from an API key.
"""
client = AsyncLlamaCloud(token=api_key, base_url=base_url)
return cls(
client,
project_id,
organization_id,
)
async def acreate_classify_job(
self,
rules: list[ClassifierRule],
@@ -173,12 +152,11 @@ class ClassifyClient:
file_input_path: str,
parsing_configuration: Optional[ClassifyParsingConfiguration] = None,
raise_on_error: bool = True,
) -> ClassifyJobResultsWithFiles:
) -> ClassifyJobResults:
file = await self.file_client.upload_file(file_input_path)
results = await self.aclassify_file_ids(
return await self.aclassify_file_ids(
rules, [file.id], parsing_configuration, raise_on_error
)
return ClassifyJobResultsWithFiles.from_classify_job_results(results, [file])
def classify_file_path(
self,
@@ -186,7 +164,7 @@ class ClassifyClient:
file_input_path: str,
parsing_configuration: Optional[ClassifyParsingConfiguration] = None,
raise_on_error: bool = True,
) -> ClassifyJobResultsWithFiles:
) -> ClassifyJobResults:
with augment_async_errors():
return asyncio.run(
self.aclassify_file_path(
@@ -202,7 +180,7 @@ class ClassifyClient:
raise_on_error: bool = True,
workers: int = DEFAULT_NUM_WORKERS,
show_progress: bool = False,
) -> ClassifyJobResultsWithFiles:
) -> ClassifyJobResults:
coroutines = [self.file_client.upload_file(path) for path in file_input_paths]
files: list[File] = await run_jobs(
coroutines,
@@ -210,10 +188,9 @@ class ClassifyClient:
workers=workers,
desc="Uploading files for classification",
)
results = await self.aclassify_file_ids(
return await self.aclassify_file_ids(
rules, [file.id for file in files], parsing_configuration, raise_on_error
)
return ClassifyJobResultsWithFiles.from_classify_job_results(results, files)
def classify_file_paths(
self,
@@ -221,7 +198,7 @@ class ClassifyClient:
file_input_paths: list[str],
parsing_configuration: Optional[ClassifyParsingConfiguration] = None,
raise_on_error: bool = True,
) -> ClassifyJobResultsWithFiles:
) -> ClassifyJobResults:
with augment_async_errors():
return asyncio.run(
self.aclassify_file_paths(
@@ -1,59 +0,0 @@
from llama_cloud.types.classify_job_results import ClassifyJobResults
from llama_cloud.types.file_classification import FileClassification
from llama_cloud.types.file import File
class FileClassificationWithFile(FileClassification):
"""
File classification with file object.
"""
file: File
@classmethod
def from_file_classification(
cls, file_classification: FileClassification, file: File
) -> "FileClassificationWithFile":
if file_classification.file_id != file.id:
raise ValueError(
f"File classification ID {file_classification.id} does not match file ID {file.id}"
)
ctor_args = {
**file_classification.dict(),
"file": file,
}
return cls(**ctor_args)
class ClassifyJobResultsWithFiles(ClassifyJobResults):
"""
Classify job results with file objects.
"""
items: list[FileClassificationWithFile]
@classmethod
def from_classify_job_results(
cls, classify_job_results: ClassifyJobResults, files: list[File]
) -> "ClassifyJobResultsWithFiles":
if len(classify_job_results.items) != len(files):
raise ValueError(
f"Number of classify job results {len(classify_job_results.items)} does not match number of files {len(files)}"
)
# create mapping of file classification result to file object
file_id_to_file: dict[str, File] = {file.id: file for file in files}
file_classification_to_file: list[tuple[FileClassification, File]] = []
for item in classify_job_results.items:
if item.file_id not in file_id_to_file:
raise ValueError(
f"File classification result {item.id} has file ID {item.file_id} that does not match any provided file ID"
)
file_classification_to_file.append((item, file_id_to_file[item.file_id]))
# create a list of file classification with file objects
ctor_args = classify_job_results.dict()
ctor_args["items"] = [
FileClassificationWithFile.from_file_classification(item, file)
for item, file in file_classification_to_file
]
return cls(**ctor_args)
+13 -4
View File
@@ -1015,11 +1015,20 @@ class LlamaParse(BasePydanticReader):
try:
url = build_url(JOB_UPLOAD_ROUTE, self.organization_id, self.project_id)
resp = await make_api_request(self.aclient, "POST", url, timeout=self.max_timeout, files=files, data=data) # type: ignore
resp.raise_for_status() # this raises if status is not 2xx
# Note: make_api_request already calls raise_for_status(), so no need to call it again
return resp.json()["id"]
except httpx.HTTPStatusError as err: # this catches it
except httpx.HTTPStatusError as err: # this catches HTTP status errors
msg = f"Failed to parse the file: {err.response.text}"
raise Exception(msg) from err # this preserves the exception context
except Exception as err: # this catches other exceptions like RetryError, ValueError, etc.
# Try to extract meaningful error message from the exception chain
if hasattr(err, '__cause__') and isinstance(err.__cause__, httpx.HTTPStatusError):
# If the exception was caused by an HTTPStatusError, extract the response text
msg = f"Failed to parse the file: {err.__cause__.response.text}"
else:
# For other exceptions, use the string representation
msg = f"Failed to parse the file: {str(err)}"
raise Exception(msg) from err
finally:
if file_handle is not None:
file_handle.close()
@@ -1578,7 +1587,7 @@ class LlamaParse(BasePydanticReader):
resp = await make_api_request(
client, "GET", asset_url, timeout=self.max_timeout
)
resp.raise_for_status()
# Note: make_api_request already calls raise_for_status()
f.write(resp.content)
assets.append(asset)
return assets
@@ -1676,7 +1685,7 @@ class LlamaParse(BasePydanticReader):
res = await make_api_request(
client, "GET", xlsx_url, timeout=self.max_timeout
)
res.raise_for_status()
# Note: make_api_request already calls raise_for_status()
f.write(res.content)
xlsx_list.append(xlsx)
return xlsx_list
-3
View File
@@ -159,9 +159,6 @@ class Page(BaseModel):
durationInSeconds: Optional[float] = Field(
default=None, description="The duration of the audio transcript in seconds."
)
slideSpeakerNotes: Optional[str] = Field(
default=None, description="The speaker notes for the slide."
)
class JobResult(BaseModel):
+12 -1
View File
@@ -11,6 +11,7 @@ from tenacity import (
wait_exponential,
retry_if_exception,
before_sleep_log,
RetryError,
)
from typing import Any, Iterable, Iterator, Optional, List, cast
@@ -300,7 +301,17 @@ async def make_api_request(
response.raise_for_status()
return response
return await _make_request(url, **httpx_kwargs)
try:
return await _make_request(url, **httpx_kwargs)
except RetryError as retry_err:
# Extract the last exception from the retry error to preserve the original error details
if retry_err.last_attempt and retry_err.last_attempt.exception():
last_exception = retry_err.last_attempt.exception()
# Re-raise the original exception to preserve error details like response.text
raise last_exception from retry_err
else:
# Fallback if we can't extract the original exception
raise retry_err
def expand_target_pages(target_pages: str) -> Iterator[int]:
+2 -2
View File
@@ -11,13 +11,13 @@ dev = [
[project]
name = "llama-parse"
version = "0.6.63"
version = "0.6.62"
description = "Parse files into RAG-Optimized formats."
authors = [{name = "Logan Markewich", email = "logan@llamaindex.ai"}]
requires-python = ">=3.9,<4.0"
readme = "README.md"
license = "MIT"
dependencies = ["llama-cloud-services>=0.6.63"]
dependencies = ["llama-cloud-services>=0.6.62"]
[project.scripts]
llama-parse = "llama_parse.cli.main:parse"
+1 -1
View File
@@ -19,7 +19,7 @@ dev = [
[project]
name = "llama-cloud-services"
version = "0.6.63"
version = "0.6.62"
description = "Tailored SDK clients for LlamaCloud services."
authors = [{name = "Logan Markewich", email = "logan@runllama.ai"}]
requires-python = ">=3.9,<4.0"
+4 -42
View File
@@ -2,7 +2,6 @@ import os
import pytest
from llama_cloud.client import AsyncLlamaCloud
from llama_cloud.types import Project, ClassifierRule, ClassifyJobResults
from llama_cloud_services.beta.classifier.types import ClassifyJobResultsWithFiles
from llama_cloud_services.beta.classifier.client import ClassifyClient
from llama_cloud_services.files.client import FileClient
from llama_cloud.errors.unprocessable_entity_error import UnprocessableEntityError
@@ -131,44 +130,6 @@ async def test_classify_file_ids(
assert item.result.type == expected_type
@pytest.mark.asyncio
async def test_classify_file_ids_from_api_key(
e2e_test_settings: EndToEndTestSettings,
file_client: FileClient,
simple_pdf_file_path: str,
research_paper_path: str,
classification_rules: list[ClassifierRule],
):
"""Test classifying files by their IDs"""
# Upload test files first to get their IDs
pdf_file = await file_client.upload_file(simple_pdf_file_path)
research_paper_file = await file_client.upload_file(research_paper_path)
classify_client = ClassifyClient.from_api_key(
api_key=e2e_test_settings.LLAMA_CLOUD_API_KEY.get_secret_value(),
base_url=e2e_test_settings.LLAMA_CLOUD_BASE_URL,
project_id=pdf_file.project_id,
organization_id=e2e_test_settings.LLAMA_CLOUD_ORGANIZATION_ID,
)
# Classify the uploaded files
results = await classify_client.aclassify_file_ids(
rules=classification_rules, file_ids=[pdf_file.id, research_paper_file.id]
)
assert isinstance(results, ClassifyJobResults)
assert len(results.items) == 2
file_id_to_expected_type = {
pdf_file.id: "number",
research_paper_file.id: "research_paper",
}
# Verify each file got classified
for item in results.items:
expected_type = file_id_to_expected_type[item.file_id]
assert item.result.type == expected_type
@parameterize_sync_and_async
@pytest.mark.asyncio
async def test_classify_file_path(
@@ -188,7 +149,7 @@ async def test_classify_file_path(
rules=classification_rules, file_input_path=simple_pdf_file_path
)
assert isinstance(results, ClassifyJobResultsWithFiles)
assert isinstance(results, ClassifyJobResults)
assert len(results.items) == 1
# Verify the file got classified
@@ -219,7 +180,7 @@ async def test_classify_file_paths(
file_input_paths=[simple_pdf_file_path, research_paper_path],
)
assert isinstance(results, ClassifyJobResultsWithFiles)
assert isinstance(results, ClassifyJobResults)
assert len(results.items) == 2
file_name_to_expected_type = {
@@ -228,7 +189,8 @@ async def test_classify_file_paths(
}
# Verify each file got classified
for item in results.items:
expected_type = file_name_to_expected_type[item.file.name]
file = await file_client.get_file(item.file_id)
expected_type = file_name_to_expected_type[file.name]
assert item.result.type == expected_type
Generated
+2256 -2256
View File
File diff suppressed because it is too large Load Diff
+14 -61
View File
@@ -8,11 +8,10 @@ import subprocess
import sys
import tomlkit
from pathlib import Path
import json
def get_current_versions() -> tuple[str, str, str, str | None]:
"""Get current versions from both pyproject.toml files and TS package.json."""
def get_current_versions() -> tuple[str, str, str]:
"""Get current versions from both pyproject.toml files."""
# Read main pyproject.toml
main_content = Path("py/pyproject.toml").read_text()
main_doc = tomlkit.parse(main_content)
@@ -35,21 +34,11 @@ def get_current_versions() -> tuple[str, str, str, str | None]:
)
break
# Read TypeScript package.json version via helper
ts_version: str = get_ts_version()
return (
str(main_version),
str(llama_parse_version),
str(dependency_version),
str(ts_version) if ts_version is not None else None,
)
return str(main_version), str(llama_parse_version), str(dependency_version)
def validate_versions(
main_version: str,
llama_parse_version: str,
dependency_version: str,
main_version: str, llama_parse_version: str, dependency_version: str
) -> list[str]:
"""Validate that versions are consistent and return warnings."""
warnings = []
@@ -71,7 +60,7 @@ def validate_versions(
def set_version(version: str) -> None:
"""Set version across Python projects (no TS change)."""
"""Set version across all pyproject.toml files using tomlkit to preserve formatting."""
# Update main pyproject.toml
main_content = Path("py/pyproject.toml").read_text()
main_doc = tomlkit.parse(main_content)
@@ -90,26 +79,7 @@ def set_version(version: str) -> None:
break
Path("py/llama_parse/pyproject.toml").write_text(tomlkit.dumps(llama_parse_doc))
click.echo(f"Updated Python versions to {version}")
def get_ts_version() -> str:
"""Read TypeScript package.json version (if present)."""
ts_package_path = Path("ts/llama_cloud_services/package.json")
package_data = json.loads(ts_package_path.read_text())
data = package_data.get("version")
if data is None:
raise RuntimeError("TypeScript package.json version not found")
return data
def set_ts_version(version: str) -> None:
"""Set TypeScript package.json version only."""
ts_package_path = Path("ts/llama_cloud_services/package.json")
package_data = json.loads(ts_package_path.read_text())
package_data["version"] = version
ts_package_path.write_text(json.dumps(package_data, indent=2) + "\n")
click.echo(f"Updated TypeScript package.json version to {version}")
click.echo(f"Updated all versions to {version}")
def get_current_branch() -> str:
@@ -129,7 +99,7 @@ def create_if_not_exists(version: str) -> None:
)
sys.exit(1)
tag_name = f"v{version}" if version[0].isdigit() else version
tag_name = f"v{version}"
if not tag_exists(version):
# Create tag
subprocess.run(["git", "tag", tag_name], check=True)
@@ -163,18 +133,12 @@ def cli() -> None:
@cli.command()
def get() -> None:
"""Get current versions and show validation warnings."""
(
main_version,
llama_parse_version,
dependency_version,
ts_version,
) = get_current_versions()
main_version, llama_parse_version, dependency_version = get_current_versions()
click.echo("Current versions:")
click.echo(f" llama-cloud-services: {main_version}")
click.echo(f" llama-parse: {llama_parse_version}")
click.echo(f" dependency reference: {dependency_version}")
click.echo(f" typescript package: {ts_version}")
warnings = validate_versions(main_version, llama_parse_version, dependency_version)
if warnings:
@@ -187,15 +151,9 @@ def get() -> None:
@cli.command()
@click.argument("version")
@click.option("--js", is_flag=True, help="Update TypeScript package.json only")
def set(version: str, js: bool) -> None:
"""Set version for Python, TypeScript, or both (default: Python only)."""
if js:
set_ts_version(version)
return
else:
set_version(version)
def set(version: str) -> None:
"""Set version across all pyproject.toml files."""
set_version(version)
@cli.command()
@@ -207,16 +165,11 @@ def set(version: str, js: bool) -> None:
is_flag=True,
help="Push the tag to the remote repository",
)
@click.option(
"--js",
is_flag=True,
help="tag TypeScript package.json only",
)
def tag(version: str | None = None, push: bool = False, js: bool = False) -> None:
def tag(version: str | None = None, push: bool = False) -> None:
"""Create and push a git tag for the current version."""
if not version:
main_version, _, _, js_version = get_current_versions()
version = f"llama-cloud-services@{js_version}" if js else main_version
main_version, _, _ = get_current_versions()
version = main_version
create_if_not_exists(version)
if push:
+1 -2
View File
@@ -1,6 +1,6 @@
{
"name": "llama-cloud-services",
"version": "0.3.4",
"version": "0.3.3",
"type": "module",
"license": "MIT",
"scripts": {
@@ -9,7 +9,6 @@
"dev": "bunchee --watch",
"lint": "eslint src/ --ignore-pattern client/*.ts --no-warn-ignored",
"format": "prettier --write ./src/",
"format:check": "prettier --check ./src/",
"test": "vitest run --testTimeout=60000",
"test:watch": "vitest --watch",
"test:ui": "vitest --ui",
@@ -1,5 +1,5 @@
import { createClient } from "@hey-api/client-fetch";
import { client as defaultClient } from "../../api";
import { createClient, createConfig } from "@hey-api/client-fetch";
import { getEnv } from "@llamaindex/env";
import {
aggregateAgentDataApiV1BetaAgentDataAggregatePost,
createAgentDataApiV1BetaAgentDataPost,
@@ -24,19 +24,36 @@ import type {
*/
export class AgentClient<T = unknown> {
private client: ReturnType<typeof createClient>;
private baseUrl: string;
private headers: Record<string, string>;
private collection: string;
private agentUrlId: string;
constructor({
client = defaultClient,
apiKey = getEnv("LLAMA_CLOUD_API_KEY"),
baseUrl = "https://api.cloud.llamaindex.ai/",
collection = "default",
agentUrlId = "_public",
}: {
client?: ReturnType<typeof createClient>;
apiKey?: string;
baseUrl?: string;
collection?: string;
agentUrlId?: string;
}) {
this.client = client;
this.baseUrl = baseUrl;
this.headers = {
"X-SDK-Name": "llamaindex-ts",
...(apiKey && { Authorization: `Bearer ${apiKey}` }),
};
this.client = createClient(
createConfig({
baseUrl: this.baseUrl,
headers: this.headers,
}),
);
this.collection = collection;
this.agentUrlId = agentUrlId;
}
@@ -264,13 +281,15 @@ export interface AgentDataClientOptions {
* @returns A new AgentClient instance
*/
export function createAgentDataClient<T = unknown>({
client = defaultClient,
apiKey,
baseUrl,
windowUrl,
env,
agentUrlId,
collection = "default",
}: {
client?: ReturnType<typeof createClient>;
apiKey?: string;
baseUrl?: string;
windowUrl?: string;
env?: Record<string, string>;
agentUrlId?: string;
@@ -302,8 +321,9 @@ export function createAgentDataClient<T = unknown>({
}
return new AgentClient({
...(apiKey && { apiKey }),
...(baseUrl && { baseUrl }),
...(agentUrlId && { agentUrlId }),
collection,
client,
});
}
+1 -1
View File
@@ -194,7 +194,7 @@ export class LlamaParseReader extends FileReader {
? this.language
: [this.language];
this.stdout =
(params.stdout ?? typeof process !== "undefined")
params.stdout ?? typeof process !== "undefined"
? process!.stdout
: undefined;
const apiKey = params.apiKey ?? getEnv("LLAMA_CLOUD_API_KEY");
@@ -1,80 +0,0 @@
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { listProjectsApiV1ProjectsGet, client } from "../src/api.js";
describe("Global client configuration", () => {
const originalFetch = globalThis.fetch;
beforeEach(() => {
vi.restoreAllMocks();
});
afterEach(() => {
globalThis.fetch = originalFetch;
});
it("adds X-SDK-Name header from global client config", async () => {
const fetchSpy = vi
.spyOn(globalThis, "fetch")
.mockImplementation(async (input, init) => {
// Validate the header is present on the outgoing request
let headers: Headers;
if (input && typeof input === "object" && "headers" in (input as any)) {
headers = (input as Request).headers;
} else {
headers = new Headers((init && init.headers) || {});
}
expect(headers.get("X-SDK-Name")).toBe("llamaindex-ts");
return new Response(JSON.stringify([]), {
status: 200,
headers: { "Content-Type": "application/json" },
});
});
// Trigger any request via the generated SDK (imported through src/api.ts)
await listProjectsApiV1ProjectsGet({ throwOnError: false });
expect(fetchSpy).toHaveBeenCalledOnce();
});
it("respects additional custom headers set via setConfig", async () => {
const prevConfig = client.getConfig();
try {
client.setConfig({
...prevConfig,
headers: {
...(prevConfig.headers || {}),
"X-Custom-Header": "custom-value",
},
});
const fetchSpy = vi
.spyOn(globalThis, "fetch")
.mockImplementation(async (input, init) => {
let headers: Headers;
if (
input &&
typeof input === "object" &&
"headers" in (input as any)
) {
headers = (input as Request).headers;
} else {
headers = new Headers((init && init.headers) || {});
}
expect(headers.get("X-SDK-Name")).toBe("llamaindex-ts");
expect(headers.get("X-Custom-Header")).toBe("custom-value");
return new Response(JSON.stringify([]), {
status: 200,
headers: { "Content-Type": "application/json" },
});
});
await listProjectsApiV1ProjectsGet({ throwOnError: false });
expect(fetchSpy).toHaveBeenCalledOnce();
} finally {
// Restore original configuration to avoid test cross-talk
client.setConfig(prevConfig);
}
});
});