diff --git a/.github/actions/setup-typescript-client/action.yml b/.github/actions/setup-typescript-client/action.yml new file mode 100644 index 000000000..05b7eb53f --- /dev/null +++ b/.github/actions/setup-typescript-client/action.yml @@ -0,0 +1,36 @@ +name: Setup TypeScript client +description: Conditionally checkout and link llama-stack-client-typescript based on client-version +inputs: + client-version: + description: 'Client version (latest or published)' + required: true + +outputs: + ts-client-path: + description: 'Path or version to use for TypeScript client' + value: ${{ steps.set-path.outputs.ts-client-path }} + +runs: + using: "composite" + steps: + - name: Checkout TypeScript client (latest) + if: ${{ inputs.client-version == 'latest' }} + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + repository: llamastack/llama-stack-client-typescript + ref: main + path: .ts-client-checkout + + - name: Set TS_CLIENT_PATH + id: set-path + shell: bash + run: | + if [ "${{ inputs.client-version }}" = "latest" ]; then + echo "ts-client-path=${{ github.workspace }}/.ts-client-checkout" >> $GITHUB_OUTPUT + elif [ "${{ inputs.client-version }}" = "published" ]; then + echo "ts-client-path=^0.3.2" >> $GITHUB_OUTPUT + else + echo "::error::Invalid client-version: ${{ inputs.client-version }}" + exit 1 + fi + diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index cad3c76e4..8073f6a15 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -101,12 +101,19 @@ jobs: cache: 'npm' cache-dependency-path: tests/integration/client-typescript/package-lock.json + - name: Setup TypeScript client + if: ${{ matrix.client == 'server' }} + id: setup-ts-client + uses: ./.github/actions/setup-typescript-client + with: + client-version: ${{ matrix.client-version }} + - name: Run tests if: ${{ matrix.config.allowed_clients == null || contains(matrix.config.allowed_clients, matrix.client) }} uses: ./.github/actions/run-and-record-tests env: OPENAI_API_KEY: dummy - RUN_CLIENT_TS_TESTS: ${{ matrix.client == 'server' && '1' || '0' }} + TS_CLIENT_PATH: ${{ steps.setup-ts-client.outputs.ts-client-path || '' }} with: stack-config: >- ${{ matrix.config.stack_config diff --git a/.gitignore b/.gitignore index 2d05d21a7..0d8fd5a2f 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ docs/docs/api-deprecated/ docs/docs/api-experimental/ docs/docs/api/ tests/integration/client-typescript/node_modules/ +.ts-client-checkout/ diff --git a/scripts/integration-tests.sh b/scripts/integration-tests.sh index a39063cb9..189f69747 100755 --- a/scripts/integration-tests.sh +++ b/scripts/integration-tests.sh @@ -20,7 +20,6 @@ TEST_PATTERN="" INFERENCE_MODE="replay" EXTRA_PARAMS="" COLLECT_ONLY=false -RUN_CLIENT_TS_TESTS="${RUN_CLIENT_TS_TESTS:-0}" # Function to display usage usage() { @@ -229,14 +228,27 @@ run_client_ts_tests() { pushd tests/integration/client-typescript >/dev/null - local install_cmd="npm install" - if [[ "${CI:-}" == "true" || "${CI:-}" == "1" ]]; then - install_cmd="npm ci" + # Determine if TS_CLIENT_PATH is a directory path or an npm version + if [[ -d "$TS_CLIENT_PATH" ]]; then + # It's a directory path - use local checkout + if [[ ! -f "$TS_CLIENT_PATH/package.json" ]]; then + echo "Error: $TS_CLIENT_PATH exists but doesn't look like llama-stack-client-typescript (no package.json)" + popd >/dev/null + return 1 + fi + echo "Using local llama-stack-client-typescript from: $TS_CLIENT_PATH" + npm install --install-links "$TS_CLIENT_PATH" + else + # It's an npm version specifier - install from npm + echo "Installing llama-stack-client@${TS_CLIENT_PATH} from npm" + if [[ "${CI:-}" == "true" || "${CI:-}" == "1" ]]; then + npm ci + npm install "llama-stack-client@${TS_CLIENT_PATH}" + else + npm install "llama-stack-client@${TS_CLIENT_PATH}" + fi fi - echo "Installing TypeScript client test dependencies using: $install_cmd" - $install_cmd - # Export env vars for the test runner to read suites.json export LLAMA_STACK_TEST_SUITE="$TEST_SUITE" # LLAMA_STACK_TEST_SETUP already exported earlier @@ -543,7 +555,8 @@ else exit 1 fi -if [[ $exit_code -eq 0 && "$RUN_CLIENT_TS_TESTS" == "1" && "${LLAMA_STACK_TEST_STACK_CONFIG_TYPE:-}" == "server" ]]; then +# Run TypeScript client tests if TS_CLIENT_PATH is set +if [[ $exit_code -eq 0 && -n "${TS_CLIENT_PATH:-}" && "${LLAMA_STACK_TEST_STACK_CONFIG_TYPE:-}" == "server" ]]; then run_client_ts_tests fi diff --git a/tests/integration/README.md b/tests/integration/README.md index 221211946..c4c1f52bd 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -214,10 +214,20 @@ def test_asymmetric_embeddings(llama_stack_client, embedding_model_id): ## TypeScript Client Replays -Setting `RUN_CLIENT_TS_TESTS=1` when running `scripts/integration-tests.sh` against a `server:` stack will replay the matching TypeScript SDK suites from `tests/integration/client-typescript/` immediately after the Python run. The mapping between suites/setups and `.test.ts` files lives in `tests/integration/client-typescript/suites.json`. This mode is enabled in CI for the `server` client jobs, and you can exercise it locally with commands such as: +TypeScript SDK tests can run alongside Python tests when testing against `server:` stacks. Set `TS_CLIENT_PATH` to the path or version of `llama-stack-client-typescript` to enable: ```bash -RUN_CLIENT_TS_TESTS=1 scripts/integration-tests.sh --stack-config server:ci-tests --suite responses --setup gpt +# Use published npm package +TS_CLIENT_PATH=^0.3.2 scripts/integration-tests.sh --stack-config server:ci-tests --suite responses --setup gpt + +# Use local checkout from ~/.cache (recommended for development) +git clone https://github.com/llamastack/llama-stack-client-typescript.git ~/.cache/llama-stack-client-typescript +TS_CLIENT_PATH=~/.cache/llama-stack-client-typescript scripts/integration-tests.sh --stack-config server:ci-tests --suite responses --setup gpt + +# Use any local path +TS_CLIENT_PATH=/path/to/llama-stack-client-typescript scripts/integration-tests.sh --stack-config server:ci-tests --suite responses --setup gpt ``` -The script installs the npm project on demand and forwards the server's `TEST_API_BASE_URL` + model defaults so the TypeScript tests can reuse the existing replay fixtures. +TypeScript tests run immediately after Python tests pass, using the same replay fixtures. The mapping between Python suites/setups and TypeScript test files is defined in `tests/integration/client-typescript/suites.json`. + +If `TS_CLIENT_PATH` is unset, TypeScript tests are skipped entirely. diff --git a/tests/integration/client-typescript/package.json b/tests/integration/client-typescript/package.json index bacecac15..e5fe1b8f5 100644 --- a/tests/integration/client-typescript/package.json +++ b/tests/integration/client-typescript/package.json @@ -6,9 +6,6 @@ "scripts": { "test": "node run-tests.js" }, - "dependencies": { - "llama-stack-client": "^0.3.2" - }, "devDependencies": { "@swc/core": "^1.3.102", "@swc/jest": "^0.2.29",