Skip to content

refactor(tests): improve e2e tests, move provider funcs - #849

Merged
steebchen merged 9 commits into
mainfrom
terragon/refactor-e2e-concurrent-tests
Sep 16, 2025
Merged

steebchen merged 9 commits into
mainfrom
terragon/refactor-e2e-concurrent-tests

Conversation

@steebchen

@steebchen steebchen commented Sep 15, 2025

Copy link
Copy Markdown
Member

Summary

  • Refactored e2e tests across multiple gateway and API test files to use a unified getConcurrentTestOptions helper for enabling concurrency and CI retries
  • Improved test setup in keys-provider.e2e.ts with a dedicated setupTestData function to create isolated test data including user, account, organization, and project
  • Enhanced test reliability by cleaning database before and after tests in keys-provider.e2e.ts
  • Added detailed assertions and logging for provider key creation tests
  • Centralized test options helpers in test-helpers.ts for consistent retry and concurrency configuration

Changes

Test Options and Concurrency

  • Introduced getConcurrentTestOptions in test-helpers.ts to combine concurrency with CI retry logic
  • Updated all e2e test files (chat-basic.e2e.ts, chat-full.e2e.ts, chat-helpers.e2e.ts, chat-json.e2e.ts, chat-reasoning.e2e.ts, chat-rs.e2e.ts, chat-streaming.e2e.ts, chat-toolcalls-result.e2e.ts, chat-toolcalls.e2e.ts) to use getConcurrentTestOptions in their describe blocks

keys-provider.e2e.ts

  • Replaced inline test options with getConcurrentTestOptions for concurrency
  • Added setupTestData async function to create unique test users, accounts, organizations, and projects for each test run
  • Added authentication step to obtain session token for API requests
  • Added cleanup hooks to delete all test data before and after tests
  • Enhanced provider key tests to skip if no API key is provided and verify database entries

Test Helpers

  • Moved getTestOptions and getConcurrentTestOptions to test-helpers.ts for reuse
  • Added comments to clarify purpose of test options helpers

Test plan

  • Verified all e2e tests run with concurrency enabled
  • Confirmed provider key tests create and validate keys correctly with isolated test data
  • Ensured tests retry on CI environment
  • Manual and CI runs show stable and consistent test execution with improved setup and teardown

🌿 Generated by Terry


ℹ️ Tag @terragon-labs to ask questions and address PR feedback

📎 Task: https://www.terragonlabs.com/task/8abc6a5b-b87a-4fc4-b06f-3af35d626c89

Summary by CodeRabbit

  • Tests
    • Centralized e2e test helpers and introduced dynamic concurrency for faster, more consistent runs.
    • Simplified environment key resolution across tests; behavior unchanged when keys are missing.
  • Refactor
    • Standardized imports to use the models package for provider utilities.
  • Chores
    • Expanded models package exports to include provider utilities for broader reuse.
    • Minor config tidy-up with no behavioral impact.
  • Notes
    • No user-facing functionality changes; application behavior remains the same.

- Introduced getConcurrentTestOptions helper in test-helpers.ts to provide consistent test options with concurrency and CI retry.
- Updated all e2e test files to use getConcurrentTestOptions instead of inline concurrent: true.
- Simplified test options management and improved consistency across test suites.

Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Sep 15, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Replaces scattered, static e2e test options with centralized, dynamic concurrency via getConcurrentTestOptions. Consolidates provider env var helpers under @llmgateway/models and re-exports provider utilities from packages/models. Refactors chat-basic.e2e.ts to use shared helpers. Minor import-path updates and a .npmrc key order change.

Changes

Cohort / File(s) Summary
Repo config
./.npmrc
Reordered keys; no semantic change.
Models and provider exports
packages/models/src/index.ts, packages/models/src/provider.ts
Added re-export of ./provider from models index; adjusted Provider type import to local "." in provider.ts.
Gateway test utilities (options centralization)
apps/gateway/src/test-utils/test-helpers.ts
Removed re-export of getProviderEnvVar; added getTestOptions and getConcurrentTestOptions that derive retries/skips and concurrency from env/models.
Shared chat e2e helpers
apps/gateway/src/chat-helpers.e2e.ts
Centralizes concurrency via getConcurrentTestOptions; imports and uses getProviderEnvVar from @llmgateway/models; re-exports getConcurrentTestOptions; applies provider env lookup in setup and logs options.
Chat e2e suites: dynamic concurrency
apps/gateway/src/chat-full.e2e.ts, apps/gateway/src/chat-json.e2e.ts, apps/gateway/src/chat-reasoning.e2e.ts, apps/gateway/src/chat-rs.e2e.ts, apps/gateway/src/chat-streaming.e2e.ts, apps/gateway/src/chat-toolcalls.e2e.ts, apps/gateway/src/chat-toolcalls-result.e2e.ts
Replaced literal { concurrent: true } with getConcurrentTestOptions() from shared helpers; bodies unchanged.
Chat basic e2e refactor to shared helpers
apps/gateway/src/chat-basic.e2e.ts
Replaced local test config/model filtering/validation utilities with imports from @/chat-helpers.e2e; removed multiple local exports; retained generateTestRequestId.
Provider keys e2e options/imports
apps/api/src/routes/keys-provider.e2e.ts
Switched to getConcurrentTestOptions({ completions: false }); updated imports to use app alias and models-based getProviderEnvVar; removed local getTestOptions logic.
Import path updates to models for provider env var
apps/gateway/src/api-individual.e2e.ts, apps/gateway/src/log-queue.e2e.ts, apps/gateway/src/chat/chat.ts
Moved getProviderEnvVar (and hasProviderEnvironmentToken in chat.ts) imports to @llmgateway/models; usage unchanged.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Runner as Vitest Runner
  participant Suite as e2e Suite (describe)
  participant Helpers as chat-helpers.e2e
  participant TestUtils as test-utils/test-helpers
  participant Models as @llmgateway/models
  Runner->>Suite: start
  Suite->>Helpers: import getConcurrentTestOptions()
  Helpers->>TestUtils: getConcurrentTestOptions(opts?)
  TestUtils->>Models: read models, provider mappings
  TestUtils-->>Helpers: { concurrent: true, retry/skip }
  Helpers-->>Suite: options object
  Note over Suite,Helpers: describe("e2e", options)
  Suite->>Helpers: beforeAllHook
  Helpers->>Models: getProviderEnvVar(providerId)
  Helpers-->>Suite: setup complete
  Runner-->>Suite: execute tests with derived concurrency
Loading
sequenceDiagram
  autonumber
  participant Test as e2e Test
  participant Models as @llmgateway/models
  Test->>Models: getProviderEnvVar(providerId)
  Models-->>Test: ENV var name (e.g., OPENAI_API_KEY)
  Test->>Test: check process.env[ENV]
  alt missing key
    Test-->>Test: skip test
  else has key
    Test-->>Test: run test
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

auto-merge

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "refactor(tests): improve e2e tests, move provider funcs" succinctly and accurately summarizes the primary changes in the PR—refactoring e2e tests (concurrency and centralized helpers) and relocating provider-related functions into models—without extraneous detail. It is concise, specific to the changes in the diff, and suitable for a teammate scanning history.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch terragon/refactor-e2e-concurrent-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot changed the title Refactor e2e tests to use concurrent test options and improve setup refactor(tests): improve e2e tests Sep 15, 2025
- Removed redundant code in e2e test files by centralizing utility functions.
- Updated test configuration methods with simplified, reusable utilities.
- Enhanced test options logic to include dynamic retries and concurrency controls.
- Replaced incorrect relative import with an explicit relative path.
- Removed unused exports and cleaned up imports for better clarity.
- Moved `getProviderEnvVar` import from test-helpers to a shared library.
- Updated references in relevant E2E test files to use the new path.
- Removed unused import from test-helpers to streamline module usage.
- Moved `getProviderEnvVar` and related logic to shared models directory.
- Updated all references to use the new shared location.
- Simplified imports and removed redundant exports across files.
@steebchen steebchen changed the title refactor(tests): improve e2e tests refactor(tests): improve e2e tests, move provider funcs Sep 16, 2025
@steebchen
steebchen marked this pull request as ready for review September 16, 2025 00:51
@steebchen
steebchen merged commit 64c6bbc into main Sep 16, 2025
15 of 16 checks passed
@steebchen
steebchen deleted the terragon/refactor-e2e-concurrent-tests branch September 16, 2025 01:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/api/src/routes/keys-provider.e2e.ts (2)

71-73: Parse the Set-Cookie header into a valid Cookie header.

Sending the raw Set-Cookie string (with attributes) as Cookie is incorrect and may fail.

-      const token = auth.headers.get("set-cookie")!;
+      const setCookie = auth.headers.get("set-cookie")!;
+      // Extract "name=value" from the first cookie
+      const cookie = setCookie.split(",")[0].split(";")[0];

...
-            Cookie: token,
+            Cookie: cookie,

Also applies to: 114-121


127-129: Do not log provider tokens in CI/test output.

json includes the provider key token; logging it leaks secrets.

-        console.log("json", json);
+        // Avoid logging sensitive key material
+        // console.log("json", { ...json, providerKey: { ...json.providerKey, token: "***redacted***" } });
apps/gateway/src/log-queue.e2e.ts (1)

63-66: Replace bracketed array indexes in toHaveProperty with dot-index notation

Use numeric dot segments (choices.0.message.content) instead of choices.[0] or choices[0]. Replace the following occurrences:

  • apps/gateway/src/log-queue.e2e.ts:64 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/chat-json.e2e.ts:55 — expect(json).toHaveProperty("choices[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/chat-helpers.e2e.ts:337 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api-individual.e2e.ts:93 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api-individual.e2e.ts:244 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api-individual.e2e.ts:286 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api-individual.e2e.ts:353 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api.spec.ts:132 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api.spec.ts:247 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api.spec.ts:451 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api.spec.ts:576 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
  • apps/gateway/src/api.spec.ts:661 — expect(json).toHaveProperty("choices.[0].message.content") → expect(json).toHaveProperty("choices.0.message.content")
🧹 Nitpick comments (13)
apps/gateway/src/api-individual.e2e.ts (2)

20-71: Add cleanup or unique IDs to avoid DB pollution across runs.
createTestData uses deterministic IDs (e.g., user-json-error). Re-runs can violate PKs and bloat state.

Consider:

  • Add a cleanup helper and call it in afterEach/afterAll, or
  • Suffix testId with a short unique token.

Example (minimal change):

-async function createTestData(testId: string) {
+async function createTestData(testId: string) {
+  const uniq = `${testId}-${Date.now().toString(36)}`;
-  const userId = `user-${testId}`;
+  const userId = `user-${uniq}`;
-  const orgId = `org-${testId}`;
+  const orgId = `org-${uniq}`;
-  const projectId = `project-${testId}`;
+  const projectId = `project-${uniq}`;
-  const userOrgId = `user-org-${testId}`;
+  const userOrgId = `user-org-${uniq}`;
-  const token = `real-token-${testId}`;
+  const token = `real-token-${uniq}`;

If you prefer cleanup, I can draft a cleanupTestData(...) and wire it into hooks.


92-98: Fix path in toHaveProperty for array index.
Use dot index to avoid fragile bracket parsing.

-function validateResponse(json: any) {
-  expect(json).toHaveProperty("choices.[0].message.content");
+function validateResponse(json: any) {
+  expect(json).toHaveProperty("choices.0.message.content");
apps/gateway/src/chat/chat.ts (1)

35-38: Consolidate imports from @llmgateway/models.
Minor readability nit: merge into a single import block.

-import {
-  getProviderEnvVar,
-  hasProviderEnvironmentToken,
-} from "@llmgateway/models";
-import {
+import {
+  getProviderEnvVar,
+  hasProviderEnvironmentToken,
   getCheapestFromAvailableProviders,
   getModelStreamingSupport,
   getProviderEndpoint,
   getProviderHeaders,
   type Model,
   type ModelDefinition,
   type ProviderModelMapping,
   models,
   prepareRequestBody,
   type BaseMessage,
   type Provider,
   type ProviderRequestBody,
   type OpenAIToolInput,
   hasMaxTokens,
   providers,
 } from "@llmgateway/models";

Also applies to: 40-55

apps/gateway/src/log-queue.e2e.ts (1)

11-15: Adopt shared concurrency helper and drop local getTestOptions.

Use the centralized helpers for consistency with the rest of the suite and to enable CI retry + concurrent runs.

Apply:

 import {
   beforeAllHook,
   beforeEachHook,
   generateTestRequestId,
+  getConcurrentTestOptions,
+  getTestOptions,
 } from "@/chat-helpers.e2e";

-// Helper function to get test options with retry for CI environment
-function getTestOptions(): TestOptions {
-  return process.env.CI ? { retry: 3 } : {};
-}
+// use shared helpers from chat-helpers.e2e

-describe("Log Queue Processing E2E", () => {
+describe("Log Queue Processing E2E", getConcurrentTestOptions(), () => {
   beforeAll(beforeAllHook);
   beforeEach(beforeEachHook);

Also applies to: 23-25, 27-29

apps/gateway/src/chat-helpers.e2e.ts (2)

24-26: Avoid duplicate getTestOptions implementations.

This local version diverges from the richer one in test-utils/test-helpers. Re-export the shared one to prevent drift.

-import { describe, expect, it, type TestOptions } from "vitest";
+import { describe, expect, it } from "vitest";
...
-// Helper function to get test options with retry for CI environment
-export function getTestOptions(): TestOptions {
-  return process.env.CI ? { retry: 3 } : {};
-}
+export { getTestOptions } from "./test-utils/test-helpers";

428-433: Remove the empty test in a helpers module.

This creates a noisy, non-informative test suite entry.

-describe("e2e", getConcurrentTestOptions(), () => {
-  it("empty", () => {
-    expect(true).toBe(true);
-  });
-});
apps/gateway/src/test-utils/test-helpers.ts (3)

17-30: Clarify skip behavior when TEST_MODELS is set (infra tests may be skipped unintentionally).

With opts.completions: false, non‑completion tests (e.g., keys/provider) get skipped if TEST_MODELS is set locally. Provide an escape hatch.

-export function getTestOptions(
-  opts: { completions?: boolean } = {
-    completions: true,
-  },
-): TestOptions {
+export function getTestOptions(
+  opts: { completions?: boolean; infra?: boolean } = { completions: true },
+): TestOptions {
   const hasTestOnly = models.some((model) =>
     model.providers.some(
       (provider: ProviderModelMapping) => provider.test === "only",
     ),
   );
-  return process.env.CI || opts?.completions
-    ? { retry: 3 }
-    : { skip: hasTestOnly || !!process.env.TEST_MODELS };
+  if (process.env.CI || opts?.completions) return { retry: 3 };
+  if (opts?.infra) return {};
+  return { skip: hasTestOnly || !!process.env.TEST_MODELS };
}

Follow‑up: pass { infra: true } from infra-only tests (e.g., provider-keys).


55-66: Gate verbose polling logs behind a flag.

These logs can spam CI; consider honoring LOG_MODE.

-  console.log(`Waiting for ${expectedCount} logs (timeout: ${maxWaitMs}ms)...`);
+  if (process.env.LOG_MODE) {
+    console.log(`Waiting for ${expectedCount} logs (timeout: ${maxWaitMs}ms)...`);
+  }

Repeat similarly for other console.log/console.warn in this helper.


165-207: Handle SSE line splits across chunks.

Current splitter can drop events if a line is split between reads. Buffer partial lines across iterations.

-      const chunk = new TextDecoder().decode(value);
-      fullContent += chunk;
-      const lines = chunk.split("\n");
+      const chunk = new TextDecoder().decode(value);
+      fullContent += chunk;
+      // Preserve partial lines across chunks
+      buffered = (buffered ?? "") + chunk;
+      const lines = buffered.split("\n");
+      buffered = lines.pop() ?? "";
       for (const line of lines) {
         if (line.startsWith("data: ")) {
           eventCount++;
           hasValidSSE = true;
           if (line === "data: [DONE]") {
             continue;
           }
           try {
             const data = JSON.parse(line.substring(6));
             chunks.push(data);

Add let buffered = ""; above the loop.

apps/gateway/src/chat-basic.e2e.ts (4)

19-21: Use crypto.randomUUID() and avoid legacy substr

Generates safer, simpler IDs; removes deprecated String.prototype.substr usage.

Apply this diff:

-export function generateTestRequestId(): string {
-  return `test-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
-}
+export function generateTestRequestId(): string {
+  return `test-${randomUUID()}`;
+}

Add import (outside selected lines):

import { randomUUID } from "node:crypto";

107-110: Remove empty text content to avoid provider 4xx/validation flakes

Some providers reject empty text chunks in a content array. Since the comment already notes special handling, safest is to drop this element.

Apply this diff:

-                  {
-                    type: "text",
-                    text: "", // empty text – note this may need special handling
-                  },

145-148: Avoid hard-coded 'zai' exception; use capability metadata

Instead of branching on providerId, push this into provider metadata (e.g., provider.promptTokensMayBeZero) or a helper assertion to keep tests declarative.


66-76: DRY up usage assertions into a helper

These identical checks appear in multiple tests. Consider an assertUsage(json, { allowZeroPrompt?: boolean }) in chat-helpers.e2e to reduce duplication and ease future changes.

Example:

export function assertUsage(json: any, opts?: { allowZeroPrompt?: boolean }) {
  expect(json).toHaveProperty("usage");
  const { prompt_tokens, completion_tokens, total_tokens } = json.usage;
  expect(typeof prompt_tokens).toBe("number");
  expect(typeof completion_tokens).toBe("number");
  expect(typeof total_tokens).toBe("number");
  if (!opts?.allowZeroPrompt) expect(prompt_tokens).toBeGreaterThan(0);
  expect(completion_tokens).toBeGreaterThan(0);
  expect(total_tokens).toBeGreaterThan(0);
}

Also applies to: 199-209

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 642bb3e and 7633c81.

📒 Files selected for processing (17)
  • .npmrc (1 hunks)
  • apps/api/src/routes/keys-provider.e2e.ts (2 hunks)
  • apps/gateway/src/api-individual.e2e.ts (1 hunks)
  • apps/gateway/src/chat-basic.e2e.ts (1 hunks)
  • apps/gateway/src/chat-full.e2e.ts (2 hunks)
  • apps/gateway/src/chat-helpers.e2e.ts (4 hunks)
  • apps/gateway/src/chat-json.e2e.ts (1 hunks)
  • apps/gateway/src/chat-reasoning.e2e.ts (2 hunks)
  • apps/gateway/src/chat-rs.e2e.ts (2 hunks)
  • apps/gateway/src/chat-streaming.e2e.ts (2 hunks)
  • apps/gateway/src/chat-toolcalls-result.e2e.ts (1 hunks)
  • apps/gateway/src/chat-toolcalls.e2e.ts (1 hunks)
  • apps/gateway/src/chat/chat.ts (1 hunks)
  • apps/gateway/src/log-queue.e2e.ts (1 hunks)
  • apps/gateway/src/test-utils/test-helpers.ts (1 hunks)
  • packages/models/src/index.ts (1 hunks)
  • packages/models/src/provider.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use top-level import; never use require() or dynamic imports

Files:

  • packages/models/src/index.ts
  • apps/gateway/src/chat/chat.ts
  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/api-individual.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/log-queue.e2e.ts
  • packages/models/src/provider.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
{apps/api,apps/gateway,apps/ui,apps/docs,packages}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Always use top-level import; never use require() or dynamic imports (e.g., import(), next/dynamic)

Files:

  • packages/models/src/index.ts
  • apps/gateway/src/chat/chat.ts
  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/api-individual.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/log-queue.e2e.ts
  • packages/models/src/provider.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
{apps/{api,gateway}/src,packages/db}/**/*.ts?(x)

📄 CodeRabbit inference engine (CLAUDE.md)

Use Drizzle ORM with the latest object syntax

Files:

  • apps/gateway/src/chat/chat.ts
  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/api-individual.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/log-queue.e2e.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
apps/{api,gateway}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

For read queries, use db().query.

.findMany() or db().query.
.findFirst()

Files:

  • apps/gateway/src/chat/chat.ts
  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/api-individual.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/log-queue.e2e.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
{apps/api,apps/gateway,packages/db}/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

{apps/api,apps/gateway,packages/db}/**/*.ts: Use Drizzle ORM with the latest object syntax for database access
For reads, use db().query.

.findMany() or db().query.
.findFirst()

Files:

  • apps/gateway/src/chat/chat.ts
  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/api-individual.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/log-queue.e2e.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
**/*.e2e.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place end-to-end tests in files matching *.e2e.ts

Place end-to-end tests in files named *.e2e.ts

Files:

  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/api-individual.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/log-queue.e2e.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
apps/gateway/src/api-individual.e2e.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Put isolated E2E tests in apps/gateway/src/api-individual.e2e.ts

Put isolated E2E test cases in apps/gateway/src/api-individual.e2e.ts

Files:

  • apps/gateway/src/api-individual.e2e.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
PR: theopenco/llmgateway#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T13:15:00.724Z
Learning: Applies to apps/gateway/src/api.e2e.ts : Put parallelized .each() E2E tests in apps/gateway/src/api.e2e.ts (uses concurrent mode)
Learnt from: CR
PR: theopenco/llmgateway#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T13:16:05.355Z
Learning: Applies to apps/gateway/src/api.e2e.ts : Put parallelizable .each() E2E tests in apps/gateway/src/api.e2e.ts (uses concurrent mode)
Learnt from: CR
PR: theopenco/llmgateway#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T13:15:00.724Z
Learning: Applies to apps/gateway/src/api-individual.e2e.ts : Put isolated E2E tests in apps/gateway/src/api-individual.e2e.ts
Learnt from: CR
PR: theopenco/llmgateway#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T13:16:05.355Z
Learning: Applies to apps/gateway/src/api-individual.e2e.ts : Put isolated E2E test cases in apps/gateway/src/api-individual.e2e.ts
📚 Learning: 2025-09-15T13:15:00.724Z
Learnt from: CR
PR: theopenco/llmgateway#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T13:15:00.724Z
Learning: Applies to apps/gateway/src/api.e2e.ts : Put parallelized .each() E2E tests in apps/gateway/src/api.e2e.ts (uses concurrent mode)

Applied to files:

  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
📚 Learning: 2025-09-15T13:16:05.355Z
Learnt from: CR
PR: theopenco/llmgateway#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T13:16:05.355Z
Learning: Applies to apps/gateway/src/api.e2e.ts : Put parallelizable .each() E2E tests in apps/gateway/src/api.e2e.ts (uses concurrent mode)

Applied to files:

  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
📚 Learning: 2025-09-15T13:15:00.724Z
Learnt from: CR
PR: theopenco/llmgateway#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T13:15:00.724Z
Learning: Applies to apps/gateway/src/api-individual.e2e.ts : Put isolated E2E tests in apps/gateway/src/api-individual.e2e.ts

Applied to files:

  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/api-individual.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-json.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/log-queue.e2e.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/gateway/src/chat-toolcalls.e2e.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
📚 Learning: 2025-09-15T13:16:05.355Z
Learnt from: CR
PR: theopenco/llmgateway#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T13:16:05.355Z
Learning: Applies to apps/gateway/src/api-individual.e2e.ts : Put isolated E2E test cases in apps/gateway/src/api-individual.e2e.ts

Applied to files:

  • apps/gateway/src/chat-helpers.e2e.ts
  • apps/gateway/src/api-individual.e2e.ts
  • apps/gateway/src/chat-reasoning.e2e.ts
  • apps/gateway/src/chat-toolcalls-result.e2e.ts
  • apps/gateway/src/chat-full.e2e.ts
  • apps/gateway/src/chat-streaming.e2e.ts
  • apps/gateway/src/log-queue.e2e.ts
  • apps/gateway/src/test-utils/test-helpers.ts
  • apps/api/src/routes/keys-provider.e2e.ts
  • apps/gateway/src/chat-rs.e2e.ts
  • apps/gateway/src/chat-basic.e2e.ts
📚 Learning: 2025-09-15T13:16:05.355Z
Learnt from: CR
PR: theopenco/llmgateway#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T13:16:05.355Z
Learning: Applies to **/*.e2e.ts : Place end-to-end tests in files named *.e2e.ts

Applied to files:

  • apps/gateway/src/chat-streaming.e2e.ts
📚 Learning: 2025-09-15T13:15:00.724Z
Learnt from: CR
PR: theopenco/llmgateway#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-15T13:15:00.724Z
Learning: Applies to **/*.e2e.ts : Place end-to-end tests in files matching *.e2e.ts

Applied to files:

  • apps/gateway/src/chat-streaming.e2e.ts
🧬 Code graph analysis (11)
apps/gateway/src/chat-helpers.e2e.ts (1)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/gateway/src/chat-reasoning.e2e.ts (2)
apps/gateway/src/chat-helpers.e2e.ts (1)
  • getConcurrentTestOptions (30-30)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/gateway/src/chat-toolcalls-result.e2e.ts (2)
apps/gateway/src/chat-helpers.e2e.ts (1)
  • getConcurrentTestOptions (30-30)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/gateway/src/chat-json.e2e.ts (1)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/gateway/src/chat-full.e2e.ts (1)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/gateway/src/chat-streaming.e2e.ts (1)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/gateway/src/test-utils/test-helpers.ts (3)
apps/gateway/src/chat-helpers.e2e.ts (1)
  • getTestOptions (25-27)
apps/gateway/src/models/index.ts (1)
  • models (7-7)
packages/models/src/models.ts (2)
  • models (159-175)
  • ProviderModelMapping (23-100)
apps/gateway/src/chat-toolcalls.e2e.ts (2)
apps/gateway/src/chat-helpers.e2e.ts (1)
  • getConcurrentTestOptions (30-30)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/api/src/routes/keys-provider.e2e.ts (1)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/gateway/src/chat-rs.e2e.ts (1)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
apps/gateway/src/chat-basic.e2e.ts (1)
apps/gateway/src/test-utils/test-helpers.ts (1)
  • getConcurrentTestOptions (36-40)
🪛 ESLint
packages/models/src/provider.ts

[error] 1-1: Resolve error: EACCES: permission denied, open '/KoUbPAlwnj'
at Object.writeFileSync (node:fs:2409:20)
at l (/home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.cjs:7:13685)
at createFilesMatcher (/home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.cjs:7:14437)
at Object.resolve (/home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import@2.32.0_eslint@9.34.0_jiti@2.5.1_/node_modules/eslint-import-resolver-typescript/lib/index.cjs:298:107)
at withResolver (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/resolve.js:180:23)
at fullResolve (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/resolve.js:201:22)
at relative (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/resolve.js:217:10)
at resolve (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/resolve.js:233:12)
at checkSourceValue (/home/jailuser/git/node_modules/.pnpm/eslint-plugin-import@2.32.0_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1___504bceda7a403f00735dcb51d6a813c7/node_modules/eslint-plugin-import/lib/rules/no-useless-path-segments.js:85:53)
at checkSourceValue (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/moduleVisitor.js:32:5)

(import/no-useless-path-segments)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build / run
  • GitHub Check: e2e-shards (1)
  • GitHub Check: e2e-shards (2)
🔇 Additional comments (17)
.npmrc (1)

2-2: LGTM: reorder only; no semantic change.

packages/models/src/index.ts (1)

2-2: Re‑export looks good; watch for cycles with provider.ts.
If provider.ts imports from the index (.), ensure there’s no type-resolution cycle. See my note on provider.ts.

apps/gateway/src/chat-toolcalls-result.e2e.ts (1)

8-16: LGTM: unified concurrent test options.
Simplifies config and keeps CI behavior consistent.

apps/gateway/src/chat-reasoning.e2e.ts (1)

8-19: LGTM: switched to getConcurrentTestOptions.
Keeps concurrency policy centralized.

apps/gateway/src/chat-full.e2e.ts (1)

10-12: LGTM: centralized concurrency via helper.
Consistent with other e2e suites.

Also applies to: 21-21

apps/gateway/src/log-queue.e2e.ts (1)

17-21: Import source changes look good.

Moving getProviderEnvVar to @llmgateway/models and keeping waitForLogByRequestId local is consistent with the PR direction.

apps/gateway/src/chat-streaming.e2e.ts (1)

17-17: Good switch to centralized concurrency options.

describe("e2e", getConcurrentTestOptions(), ...) aligns with the new helper.

apps/gateway/src/chat-toolcalls.e2e.ts (1)

16-16: Concurrency helper usage LGTM.

Consistent with other e2e files.

apps/gateway/src/chat-rs.e2e.ts (1)

19-19: Concurrency helper usage LGTM.

Matches suite-wide pattern.

apps/gateway/src/chat-json.e2e.ts (1)

16-16: Concurrency helper usage LGTM.

Consistent with shared helper adoption.

apps/gateway/src/chat-helpers.e2e.ts (2)

7-11: Importing getProviderEnvVar from models is correct.

Centralizing provider utilities under @llmgateway/models is the right direction.


29-31: Re-exporting getConcurrentTestOptions here is good.

Keeps a single import surface for tests.

apps/gateway/src/test-utils/test-helpers.ts (2)

36-41: Concurrency wrapper looks good.

Simple composition over getTestOptions.


102-110: Use Drizzle query API for reads (replace select().from() with db.query.*)

File: apps/gateway/src/test-utils/test-helpers.ts (lines 102–110). Prefer db.query.log.findFirst over the raw select().from() per project guidelines.

-    // Query for the specific log entry by request ID
-    const logs = await db
-      .select()
-      .from(tables.log)
-      .where(eq(tables.log.requestId, requestId))
-      .limit(1);
-
-    const log = logs[0] || null;
+    // Query for the specific log entry by request ID (Drizzle query API)
+    const log = await db.query.log.findFirst({
+      where: eq(tables.log.requestId, requestId),
+    });

Verification attempted with rg returned no output; cannot confirm other occurrences — manual verification required.

apps/gateway/src/chat-basic.e2e.ts (3)

5-14: Align helper import path with relocation to test-helpers.ts

Per PR summary, getConcurrentTestOptions/getTestOptions moved to test-helpers.ts. This file still imports them from "@/chat-helpers.e2e". Confirm re‑export, or switch to importing from "@/test-utils/test-helpers" to avoid drift/cycles.

Apply if not re‑exported:

 import {
   beforeAllHook,
   beforeEachHook,
-  getConcurrentTestOptions,
-  getTestOptions,
   logMode,
   providerModels,
   testModels,
   validateLogByRequestId,
   validateResponse,
 } from "@/chat-helpers.e2e";
+import { getConcurrentTestOptions, getTestOptions } from "@/test-utils/test-helpers";

23-23: Confirm describe() options are honored; fallback to describe.concurrent if not

Vitest supports per‑test options; describe‑level options support can vary. Ensure getConcurrentTestOptions() at suite level is effective. If not, prefer describe.concurrent(...) and keep per‑test getTestOptions().

Optional change if needed:

-describe("e2e", getConcurrentTestOptions(), () => {
+describe.concurrent("e2e", () => {

28-31: Nice centralization of test options

Switching to shared helpers for retries/concurrency reduces boilerplate and keeps CI knobs consistent.

? { retry: 3 }
: { skip: hasTestOnly || !!process.env.TEST_MODELS };
}
import { getConcurrentTestOptions } from "../../../gateway/src/test-utils/test-helpers";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid cross-app relative import for test helpers.

../../../gateway/src/test-utils/test-helpers is brittle and likely violates lint rules. Move helpers to a shared package (e.g., packages/test-helpers) and import from there, or re-export via a workspace alias.

Follow‑up: if rehoming is out of scope for this PR, duplicate a minimal wrapper locally and plan a follow-up refactor.

🤖 Prompt for AI Agents
In apps/api/src/routes/keys-provider.e2e.ts around line 11, the test imports a
helper via a brittle cross-app relative path
("../../../gateway/src/test-utils/test-helpers"); replace this by either moving
the helper into a shared test-helpers package (e.g., packages/test-helpers) and
updating the import to that package, or, if rehoming is out of scope for this
PR, create a minimal local wrapper copy of the required helper in
apps/api/src/test-utils (or similar) and import it from there, then add a
follow-up ticket to re-export or deduplicate into a workspace-shared module so
lint rules and repo boundaries are respected.

Comment on lines 18 to 21
describe(
"e2e tests for provider keys",
{ concurrent: true, ...getTestOptions() },
getConcurrentTestOptions({ completions: false }),
() => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Double-check skip semantics with getConcurrentTestOptions({ completions: false }).

With the current helper, local runs with TEST_MODELS may skip these infra tests. Consider an infra: true option (see suggested change in helpers) and use getConcurrentTestOptions({ completions: false, infra: true }).


🏁 Script executed:

#!/bin/bash
# Grep helper implementation to confirm current skip logic
rg -n "getConcurrentTestOptions|getTestOptions" apps/gateway/src/test-utils/test-helpers.ts -n -A3 -B3

Length of output: 535


Add an infra flag to test helpers and opt infra tests into it.

getConcurrentTestOptions currently only accepts { completions?: boolean } (apps/gateway/src/test-utils/test-helpers.ts); extend getTestOptions/getConcurrentTestOptions to accept infra?: boolean (default false) and update the call in apps/api/src/routes/keys-provider.e2e.ts (around lines 18–21) to getConcurrentTestOptions({ completions: false, infra: true }).

🤖 Prompt for AI Agents
In apps/api/src/routes/keys-provider.e2e.ts around lines 18 to 21, the test uses
getConcurrentTestOptions({ completions: false }) but the test helpers need to
support an infra flag so infra tests can be opted-in; update the test-helpers
(apps/gateway/src/test-utils/test-helpers.ts) to extend both getTestOptions and
getConcurrentTestOptions signatures to accept an optional infra?: boolean
(default false) and wire that flag through to any internal option objects or
behavior, then change this call to getConcurrentTestOptions({ completions:
false, infra: true }) so the e2e file opts into infra tests.

@@ -1,4 +1,4 @@
import type { Provider } from "@llmgateway/models";
import type { Provider } from ".";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid barrel import here to prevent circular dependency.
provider.ts imports types from ".", and index.ts now re‑exports "./provider", creating a cycle. Use a direct types import.

Apply this diff:

-import type { Provider } from ".";
+import type { Provider } from "./types";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import type { Provider } from ".";
import type { Provider } from "./types";
🧰 Tools
🪛 ESLint

[error] 1-1: Resolve error: EACCES: permission denied, open '/KoUbPAlwnj'
at Object.writeFileSync (node:fs:2409:20)
at l (/home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.cjs:7:13685)
at createFilesMatcher (/home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.cjs:7:14437)
at Object.resolve (/home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import@2.32.0_eslint@9.34.0_jiti@2.5.1_/node_modules/eslint-import-resolver-typescript/lib/index.cjs:298:107)
at withResolver (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/resolve.js:180:23)
at fullResolve (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/resolve.js:201:22)
at relative (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/resolve.js:217:10)
at resolve (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/resolve.js:233:12)
at checkSourceValue (/home/jailuser/git/node_modules/.pnpm/eslint-plugin-import@2.32.0_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1___504bceda7a403f00735dcb51d6a813c7/node_modules/eslint-plugin-import/lib/rules/no-useless-path-segments.js:85:53)
at checkSourceValue (/home/jailuser/git/node_modules/.pnpm/eslint-module-utils@2.12.1_@typescript-eslint+parser@8.39.1_eslint@9.34.0_jiti@2.5.1__t_0245afd672d291ebf09c60ebb405cf51/node_modules/eslint-module-utils/moduleVisitor.js:32:5)

(import/no-useless-path-segments)

🤖 Prompt for AI Agents
In packages/models/src/provider.ts around line 1, the file currently uses a
barrel import (import type { Provider } from ".") which creates a circular
dependency because index.ts re-exports "./provider"; replace the barrel import
with a direct type import from the module that actually declares the Provider
type (e.g., import type { Provider } from "./types" or the exact file path where
Provider is defined), ensuring the new import uses a relative path to that
declaration to break the cycle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant