Skip to content

feat(sdk): add embed() and embedMany() support across providers and s… - #855

Merged
sinha-sahil merged 1 commit into
releasefrom
feat/embed-support-google-provider
Mar 7, 2026
Merged

sinha-sahil merged 1 commit into
releasefrom
feat/embed-support-google-provider

Conversation

@sinha-sahil

@sinha-sahil sinha-sahil commented Mar 7, 2026 •

Copy link
Copy Markdown
Collaborator

…erver

  • Add embed() and embedMany() to Google AI Studio provider with gemini-embedding-001 default
  • Add embedMany() to Google Vertex, OpenAI, and Amazon Bedrock providers
  • Add embedMany() base stub in BaseProvider with descriptive error for unsupported providers
  • Add embed and embedMany to AIProvider type interface
  • Add POST /api/agent/embed and POST /api/agent/embed-many server routes
  • Add EmbedRequest, EmbedResponse, EmbedManyRequest, EmbedManyResponse server types
  • Add EmbedRequestSchema and EmbedManyRequestSchema Zod validation schemas
  • Replace dynamic imports of embed/embedMany with static imports from "ai" in all providers
  • Update SDK API reference, server adapters guide, advanced API reference, and AIProvider docs
  • Update agent routes test to account for new embedding endpoints

Pull Request

Description

What does this PR do?

A clear and concise description of the changes in this pull request.

Related Issues

Does this PR close any issues?

Fixes #(issue number)
Closes #(issue number)
Relates to #(issue number)

Type of Change

Please select the type of change:

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test coverage improvement
  • Build/CI configuration
  • Other (please describe):

Motivation and Context

Why is this change needed? What problem does it solve?

Provide context for reviewers:

  • Background information
  • Use case or scenario
  • Links to relevant discussions or documentation
  • Screenshots/GIFs (if UI-related)

Changes Made

What specific changes were made?

Provide a bullet-point list of the key changes:

  • Added X functionality to Y component
  • Modified Z behavior to handle edge case A
  • Updated documentation in file B
  • Refactored C for better performance

Breaking Changes

Does this PR introduce breaking changes?

  • No breaking changes
  • Yes, breaking changes (describe below)

If yes, describe:

  • What breaks?
  • Migration path for users
  • Deprecation warnings added?

Testing

How has this been tested?

Please describe the tests you ran and their results:

  • Unit tests added/updated
  • Integration tests added/updated
  • E2E tests pass
  • Manual testing completed
  • Tested with multiple providers: [list providers]
  • Tested on multiple platforms: [list platforms]

Test Coverage

  • All new code is covered by tests
  • Existing tests pass
  • Coverage percentage maintained or improved

Manual Testing Steps

Provide steps for manual testing:

  1. Set up environment with [...]
  2. Run command [...]
  3. Verify that [...]
  4. Check that [...]

Code Quality

Have you followed code quality standards?

  • Code follows the project's style guidelines (ESLint passes)
  • Code is properly formatted (Prettier applied)
  • Self-review of code completed
  • No console.log statements (using logger instead)
  • No hardcoded API keys or secrets
  • TypeScript strict mode compliance
  • Proper error handling implemented
  • TODO/FIXME comments reference issues

Documentation

Have you updated documentation?

  • JSDoc comments added/updated for public APIs
  • README.md updated (if needed)
  • Documentation in /docs updated (if needed)
  • Code examples added/updated (if needed)
  • CHANGELOG.md updated (if applicable)
  • Migration guide provided (if breaking changes)

Commit Message Format

Does your commit follow semantic commit conventions?

  • Commit message follows format: type(scope): description
  • Valid type used: feat, fix, docs, style, refactor, test, chore, build, ci, perf, revert
  • Scope specified (e.g., providers, cli, docs, middleware)

Example: feat(providers): add support for LiteLLM proxy

Dependencies

Does this PR add, update, or remove dependencies?

  • No dependency changes
  • Dependencies added (list below)
  • Dependencies updated (list below)
  • Dependencies removed (list below)

If yes, list dependencies and justification:

package-name@version - Reason for adding/updating

Performance Impact

Does this change affect performance?

  • No performance impact
  • Performance improved (provide metrics)
  • Performance degraded (justify why acceptable)

If applicable, provide benchmark results:

Before: X ms
After: Y ms
Improvement: Z%

Security Considerations

Are there any security implications?

  • No security implications
  • Security review needed
  • Security vulnerability fixed

If applicable, describe:

  • Security measures implemented
  • Potential risks mitigated
  • Compliance considerations (HIPAA, SOC2, GDPR)

Deployment Notes

Special deployment instructions?

  • No special deployment steps
  • Requires environment variable changes (list below)
  • Requires database migration
  • Requires Redis schema update
  • Other (describe below)

Screenshots / Videos

If applicable, add screenshots or videos to demonstrate changes:

[Add screenshots or videos here]

Reviewer Checklist

For reviewers:

  • Code follows project style and conventions
  • Changes are well-documented
  • Tests provide adequate coverage
  • No obvious performance issues
  • No security vulnerabilities introduced
  • Breaking changes are properly documented
  • Documentation is clear and accurate

Additional Notes

Any additional information for reviewers:

[Add any extra context, concerns, or questions here]


Pre-submission Checklist

Before submitting, ensure you have:

  • Read and followed the Contributing Guidelines
  • Verified all automated pre-commit checks pass
  • Tested changes locally with pnpm test
  • Built the project successfully with pnpm build
  • Run pnpm run validate:all and all checks pass
  • Reviewed your own code for obvious issues
  • Ensured commit messages follow semantic format
  • Updated relevant documentation
  • Added tests for new functionality
  • Checked that CI/CD pipeline passes (after creating PR)

Thank you for contributing to NeuroLink!

Summary by CodeRabbit

  • New Features

    • Added embedding generation endpoints: /api/agent/embed for single embeddings and /api/agent/embed-many for batch processing.
    • Extended embedding support across multiple AI providers.
    • Batch embeddings now support up to 2,048 texts per request.
  • Documentation

    • Comprehensive guides added for embedding API usage, providers, and supported models.

@sinha-sahil
sinha-sahil requested a review from murdore March 7, 2026 09:17
@vercel

vercel Bot commented Mar 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
neurolink Ready Ready Preview, Comment Mar 7, 2026 10:47am

@github-actions

github-actions Bot commented Mar 7, 2026 •

Copy link
Copy Markdown
Contributor

✅ Single Commit Policy - COMPLIANT

Status: Policy requirements met • 1 commit • Valid format • Ready for merge

📊 View validation details

📝 Commit Details

  • Hash: ecaf73ec2f1bca8561b63577e1bbfe9f35ede444
  • Message: feat(sdk): add embed() and embedMany() support across providers and server
  • Author: Sahil Sinha

✅ Validation Results

  • Single commit requirement met
  • No merge commits in branch
  • Semantic commit message format verified
  • Ready for squash merge to release branch

🤖 Automated validation by NeuroLink Single Commit Enforcement

@coderabbitai

coderabbitai Bot commented Mar 7, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 917f71c8-9a8e-4ef7-87e7-3809852839c8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR adds comprehensive embedding support by introducing embed() and embedMany() methods to the AIProvider interface, implementing these across multiple providers (OpenAI, Google AI Studio, Google Vertex, Amazon Bedrock), and exposing two new API endpoints (/api/agent/embed and /api/agent/embed-many) with corresponding request/response types, validation schemas, and documentation.

Changes

Cohort / File(s) Summary
Documentation
CLAUDE.md, docs/advanced/api-reference.md, docs/api/type-aliases/AIProvider.md, docs/guides/server-adapters/index.md, docs/sdk/api-reference.md
Added embedding endpoint documentation, API reference details for new embed/embedMany methods, provider support tables, and example JSON payloads for single and batch embedding operations.
Core Types & Base Provider
src/lib/types/providers.ts, src/lib/core/baseProvider.ts
Added embed() and embedMany() method signatures to AIProvider interface; BaseProvider implements default embedMany() with error logging for unsupported providers.
Provider Implementations
src/lib/providers/openAI.ts, src/lib/providers/googleAiStudio.ts, src/lib/providers/googleVertex.ts, src/lib/providers/amazonBedrock.ts
Implemented embed() and embedMany() methods across four providers with model selection defaults, logging, error handling, and batch processing (via Promise.all or direct API calls).
Server Routes & API Types
src/lib/server/routes/agentRoutes.ts, src/lib/server/types.ts, src/lib/server/utils/validation.ts
Added two new endpoints (POST /api/agent/embed, POST /api/agent/embed-many), introduced request/response types (EmbedRequest/Response, EmbedManyRequest/Response), and created corresponding Zod validation schemas with constraints on text length and batch size.
Tests
test/unit/server/routes/agentRoutes.test.ts
Updated route count expectation from 3 to 5 routes to reflect the two new embedding endpoints.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Server as Server<br/>(agentRoutes)
    participant Provider as Provider<br/>(e.g., OpenAI)
    participant AISDK as AI SDK
    
    Client->>Server: POST /api/agent/embed<br/>(text, provider, model?)
    Server->>Server: Validate EmbedRequest
    Server->>Server: Resolve Provider instance
    Server->>Provider: embed(text, modelName?)
    Provider->>AISDK: Create embedding model<br/>& call embed
    AISDK-->>Provider: embedding vector
    Provider-->>Server: number[]
    Server->>Server: Construct response<br/>(embedding, provider, model, dimension)
    Server-->>Client: EmbedResponse (200)
Loading
sequenceDiagram
    actor Client
    participant Server as Server<br/>(agentRoutes)
    participant Provider as Provider<br/>(e.g., OpenAI)
    participant AISDK as AI SDK
    
    Client->>Server: POST /api/agent/embed-many<br/>(texts[], provider?, model?)
    Server->>Server: Validate EmbedManyRequest
    Server->>Server: Resolve Provider instance
    Server->>Provider: embedMany(texts[], modelName?)
    Provider->>AISDK: Create embedding model<br/>& call embedMany
    AISDK-->>Provider: embedding vectors[][]
    Provider-->>Server: number[][]
    Server->>Server: Construct response<br/>(embeddings, provider, model, count, dimension)
    Server-->>Client: EmbedManyResponse (200)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

released

Suggested reviewers

  • murdore

Poem

🐰 Embeddings hop through vectors bright,
Four providers now embed with might!
From single texts to batches deep,
AI dreams encoded we shall reap. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding embed() and embedMany() support across providers and server, which is the core objective of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/embed-support-google-provider

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 commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@github-actions

github-actions Bot commented Mar 7, 2026 •

Copy link
Copy Markdown
Contributor

Documentation Validation Results

🚀 Documentation validation passed!

Check Status Result
Frontmatter Validation ✅ Passed
TypeScript Check ✅ Passed
Build ✅ Passed
Link Validation ✅ Passed

📦 Build artifact uploaded successfully. Ready for deployment preview.

Commit: 754fb4d6c5ef2c4544763c2f2d7c1b3e900b004c | Workflow: View logs

@github-actions

github-actions Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/advanced/api-reference.md`:
- Around line 25-80: The docs page mixes two API surfaces: the new /api/agent/*
endpoints (e.g., /api/agent/embed, /api/agent/embed-many) and older endpoints
(/api/generate, /api/stream, /api/status); fix by choosing one of two
approaches—either migrate the legacy endpoints to the /api/agent namespace
(update all examples, request/response fields, and references to use
/api/agent/generate, /api/agent/stream, /api/agent/status) or split the page
into clearly labeled sections "Current API (/api/agent/...)" and "Legacy API
(/api/...)" with a short deprecation note and consistent examples for each
section—ensure all endpoint paths and example bodies reference the chosen
namespace consistently.

In `@docs/sdk/api-reference.md`:
- Around line 487-495: The docs table adds GOOGLE_AI_EMBEDDING_MODEL and
VERTEX_EMBEDDING_MODEL but the Environment Configuration section doesn't list
them; update that main env section to document these two variables
(GOOGLE_AI_EMBEDDING_MODEL, VERTEX_EMBEDDING_MODEL), include their purpose as
embedding model overrides for Google AI Studio and Google Vertex respectively,
indicate default behavior when unset, and add them to any ENV key/value table or
example so readers can discover and use these overrides.

In `@src/lib/core/baseProvider.ts`:
- Around line 1096-1108: The embedMany method on BaseProvider lacks
timeout/abort propagation and throws a raw Error for unsupported batch
embedding; wrap the async work in the withTimeout (or withTimeoutAbortSignal)
utility so callers can enforce timeouts/abort signals and accept an optional
AbortSignal/timeout param, and replace the thrown Error with a typed error
created by ErrorFactory (e.g., ErrorFactory.create or the project-standard
factory) that indicates "Batch embedding not supported by providerName" and
includes providerName and supported provider list; update the embedMany
signature to accept and pass through timeout/abort controls and ensure the
logger call remains but the failure path uses the ErrorFactory-created error.

In `@src/lib/providers/amazonBedrock.ts`:
- Around line 2109-2130: The embedMany function currently fans out with
Promise.all causing unbounded concurrent Bedrock requests and duplicates the
default model literal; change embedMany to derive the model via
getDefaultEmbeddingModel() when modelName is absent, and replace
Promise.all(texts.map(...)) with a controlled concurrent mapper (e.g., use a
limited-concurrency iterator or p-map-style helper) that calls this.embed(text,
embeddingModelName) with a sensible concurrency limit to avoid request spikes
and timeouts; keep logging and return shape the same but ensure you await the
concurrency-limited mapping so embeddings are returned as number[][].

In `@src/lib/providers/openAI.ts`:
- Around line 741-742: embedMany currently hardcodes "text-embedding-3-small"
instead of using the configured default; update the function so that when
modelName is falsy it calls getDefaultEmbeddingModel() (same behavior as other
embedding helpers) and uses that result as embeddingModelName, ensuring batch
embeddings honor OPENAI_EMBEDDING_MODEL and produce the expected vector
dimension; modify embedMany to derive embeddingModelName = modelName ||
getDefaultEmbeddingModel().

In `@src/lib/server/routes/agentRoutes.ts`:
- Around line 230-240: Wrap the async calls that create and use the provider
with the withTimeout utility: when obtaining providerName and calling
ProviderFactory.createProvider(providerName, request.model) wrap that Promise
with withTimeout and likewise wrap provider.embedMany(request.texts,
request.model) with withTimeout so both operations enforce the same timeout
semantics; ensure you import/use the same timeout duration or error handling
pattern used by the /embed endpoint and propagate or handle timeout errors
consistently within the agentRoutes handler.
- Around line 181-188: Wrap the async calls to ProviderFactory.createProvider
and provider.embed with the withTimeout utility to enforce consistent timeouts
(use the same timeout value used elsewhere or pass a configurable timeout).
Update the code around ProviderFactory.createProvider(...) and embedding via
provider.embed(...) so both calls are invoked through withTimeout(...) and
properly await or catch timeout errors. Also address the default provider
mismatch by either removing the literal default "openai" so
ProviderFactory.createProvider decides the default, or add a comment documenting
the intentional override of the factory default; reference
ProviderFactory.createProvider, provider.embed, and withTimeout when making
these changes.

In `@src/lib/server/utils/validation.ts`:
- Around line 127-140: The current EmbedRequestSchema and EmbedManyRequestSchema
use z.string().min(1) which allows whitespace-only strings; update both schemas
to trim input before applying the length check so pure-whitespace texts are
rejected: for EmbedRequestSchema change the text field to trim the string (e.g.,
via z.string().transform(s => s.trim()) or use refine with s.trim()) and then
apply .min(1, "Text is required"); for EmbedManyRequestSchema update the array
item schema (the z.array element) to perform the same trim+min(1, ...)
transformation so each entry is validated after trimming while keeping the
array-level .min(1, "At least one text is required") and .max(2048, ...) intact.

In `@test/unit/server/routes/agentRoutes.test.ts`:
- Around line 89-90: Add unit tests exercising the two new embedding routes
(/agent/embed and /agent/embed-many) rather than only updating the route count:
add mocked happy-path tests that POST to "/agent/embed" and "/agent/embed-many"
asserting the handler response shape and that the default provider selection
logic runs, and add validation-error tests that send invalid payloads and assert
the handlers return the expected validation errors. In both tests mock external
API calls used by the embed and embed-many handlers (e.g., the embedding
provider client) so they return deterministic embeddings, and place assertions
on the handler functions (embed handler names or the route paths) to confirm
request validation, provider defaulting, and response shaping behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4ce55677-2f42-473e-b8cc-c8d3dae64994

📥 Commits

Reviewing files that changed from the base of the PR and between fa62235 and c0425d8.

📒 Files selected for processing (15)
  • CLAUDE.md
  • docs/advanced/api-reference.md
  • docs/api/type-aliases/AIProvider.md
  • docs/guides/server-adapters/index.md
  • docs/sdk/api-reference.md
  • src/lib/core/baseProvider.ts
  • src/lib/providers/amazonBedrock.ts
  • src/lib/providers/googleAiStudio.ts
  • src/lib/providers/googleVertex.ts
  • src/lib/providers/openAI.ts
  • src/lib/server/routes/agentRoutes.ts
  • src/lib/server/types.ts
  • src/lib/server/utils/validation.ts
  • src/lib/types/providers.ts
  • test/unit/server/routes/agentRoutes.test.ts

Comment on lines +25 to +80
## Embeddings

### Generate Embedding

```http
POST /api/agent/embed
```

**Request body:**

```json
{
"text": "Hello world",
"provider": "googleAiStudio",
"model": "gemini-embedding-001"
}
```

**Response:**

```json
{
"embedding": [0.123, -0.456, ...],
"provider": "googleAiStudio",
"model": "gemini-embedding-001",
"dimension": 768
}
```

### Generate Batch Embeddings

```http
POST /api/agent/embed-many
```

**Request body:**

```json
{
"texts": ["First document", "Second document", "Third document"],
"provider": "openai",
"model": "text-embedding-3-small"
}
```

**Response:**

```json
{
"embeddings": [[0.123, -0.456, ...], [0.789, -0.012, ...], [0.345, -0.678, ...]],
"provider": "openai",
"model": "text-embedding-3-small",
"count": 3,
"dimension": 1536
}
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

This page now mixes two different API surfaces.

The new section documents /api/agent/* endpoints, but the same page still lists /api/generate, /api/stream, and /api/status above. That makes the reference internally inconsistent and likely sends readers to routes that do not exist on the current server API. Please either migrate the older sections to the same namespace or split legacy/current APIs explicitly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/advanced/api-reference.md` around lines 25 - 80, The docs page mixes two
API surfaces: the new /api/agent/* endpoints (e.g., /api/agent/embed,
/api/agent/embed-many) and older endpoints (/api/generate, /api/stream,
/api/status); fix by choosing one of two approaches—either migrate the legacy
endpoints to the /api/agent namespace (update all examples, request/response
fields, and references to use /api/agent/generate, /api/agent/stream,
/api/agent/status) or split the page into clearly labeled sections "Current API
(/api/agent/...)" and "Legacy API (/api/...)" with a short deprecation note and
consistent examples for each section—ensure all endpoint paths and example
bodies reference the chosen namespace consistently.

Comment thread docs/sdk/api-reference.md
Comment on lines +487 to +495
**Supported providers and default models:**

| Provider | Default Embedding Model | Env Override |
| ---------------- | ------------------------------ | --------------------------- |
| OpenAI | `text-embedding-3-small` | — |
| Google AI Studio | `gemini-embedding-001` | `GOOGLE_AI_EMBEDDING_MODEL` |
| Google Vertex | `text-embedding-004` | `VERTEX_EMBEDDING_MODEL` |
| Amazon Bedrock | `amazon.titan-embed-text-v2:0` | — |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Document these embedding override vars in the main env section.

This table introduces GOOGLE_AI_EMBEDDING_MODEL and VERTEX_EMBEDDING_MODEL, but the later Environment Configuration section in this same file does not list them. Users looking there for the supported env vars will miss these overrides.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/sdk/api-reference.md` around lines 487 - 495, The docs table adds
GOOGLE_AI_EMBEDDING_MODEL and VERTEX_EMBEDDING_MODEL but the Environment
Configuration section doesn't list them; update that main env section to
document these two variables (GOOGLE_AI_EMBEDDING_MODEL,
VERTEX_EMBEDDING_MODEL), include their purpose as embedding model overrides for
Google AI Studio and Google Vertex respectively, indicate default behavior when
unset, and add them to any ENV key/value table or example so readers can
discover and use these overrides.

Comment on lines +1096 to +1108
async embedMany(texts: string[], _modelName?: string): Promise<number[][]> {
logger.warn(
`embedMany() called on ${this.providerName} which does not have a native implementation`,
{
count: texts.length,
},
);
throw new Error(
`Batch embedding generation is not supported by the ${this.providerName} provider. ` +
`Supported providers: openai, googleAiStudio, vertex/google, bedrock. ` +
`Use an embedding model like text-embedding-3-small (OpenAI), gemini-embedding-001 (Google AI), ` +
`text-embedding-004 (Vertex), or amazon.titan-embed-text-v2:0 (Bedrock).`,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Harden embedMany() before exposing it via HTTP.

The new signature has no way to propagate timeout/abort control, and the fallback throws a raw Error when batching is unsupported. That leaves /api/agent/embed-many prone to hung requests on provider stalls and generic 500s for capability misses; please carry timeout/abort through this API and use ErrorFactory for the unsupported-provider path.

As per coding guidelines, "All async operations should be wrapped with withTimeout utility for consistent timeout handling" and "Use ErrorFactory for creating typed errors instead of throwing raw Error objects"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/core/baseProvider.ts` around lines 1096 - 1108, The embedMany method
on BaseProvider lacks timeout/abort propagation and throws a raw Error for
unsupported batch embedding; wrap the async work in the withTimeout (or
withTimeoutAbortSignal) utility so callers can enforce timeouts/abort signals
and accept an optional AbortSignal/timeout param, and replace the thrown Error
with a typed error created by ErrorFactory (e.g., ErrorFactory.create or the
project-standard factory) that indicates "Batch embedding not supported by
providerName" and includes providerName and supported provider list; update the
embedMany signature to accept and pass through timeout/abort controls and ensure
the logger call remains but the failure path uses the ErrorFactory-created
error.

Comment on lines +2109 to +2130
async embedMany(texts: string[], modelName?: string): Promise<number[][]> {
const embeddingModelName = modelName || "amazon.titan-embed-text-v2:0";

logger.debug("Generating batch embeddings", {
provider: this.providerName,
model: embeddingModelName,
count: texts.length,
});

try {
const embeddings = await Promise.all(
texts.map((text) => this.embed(text, embeddingModelName)),
);

logger.debug("Batch embeddings generated successfully", {
provider: this.providerName,
model: embeddingModelName,
count: embeddings.length,
embeddingDimension: embeddings[0]?.length,
});

return embeddings;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Bound batch fan-out before calling Bedrock.

Promise.all sends one Bedrock request per text with no concurrency cap. Large embed-many payloads will spike outbound calls, which makes throttling and timeout storms much more likely here. Also, this duplicates the default model literal instead of reusing getDefaultEmbeddingModel().

♻️ Suggested change
   async embedMany(texts: string[], modelName?: string): Promise<number[][]> {
-    const embeddingModelName = modelName || "amazon.titan-embed-text-v2:0";
+    const embeddingModelName = modelName || this.getDefaultEmbeddingModel();
@@
-      const embeddings = await Promise.all(
-        texts.map((text) => this.embed(text, embeddingModelName)),
-      );
+      const embeddings: number[][] = [];
+      const batchSize = 5;
+
+      for (let i = 0; i < texts.length; i += batchSize) {
+        const batch = texts.slice(i, i + batchSize);
+        embeddings.push(
+          ...(await Promise.all(
+            batch.map((text) => this.embed(text, embeddingModelName)),
+          )),
+        );
+      }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/providers/amazonBedrock.ts` around lines 2109 - 2130, The embedMany
function currently fans out with Promise.all causing unbounded concurrent
Bedrock requests and duplicates the default model literal; change embedMany to
derive the model via getDefaultEmbeddingModel() when modelName is absent, and
replace Promise.all(texts.map(...)) with a controlled concurrent mapper (e.g.,
use a limited-concurrency iterator or p-map-style helper) that calls
this.embed(text, embeddingModelName) with a sensible concurrency limit to avoid
request spikes and timeouts; keep logging and return shape the same but ensure
you await the concurrency-limited mapping so embeddings are returned as
number[][].

Comment on lines +741 to +742
async embedMany(texts: string[], modelName?: string): Promise<number[][]> {
const embeddingModelName = modelName || "text-embedding-3-small";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Honor the configured default embedding model in batch mode.

This new path hardcodes "text-embedding-3-small" instead of using getDefaultEmbeddingModel(). If a deployment sets OPENAI_EMBEDDING_MODEL to a different model, embedMany() will still emit 3-small vectors here, which can break downstream stores that expect the configured embedding dimension.

Suggested fix
-    const embeddingModelName = modelName || "text-embedding-3-small";
+    const embeddingModelName =
+      modelName || this.getDefaultEmbeddingModel() || "text-embedding-3-small";
📝 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
async embedMany(texts: string[], modelName?: string): Promise<number[][]> {
const embeddingModelName = modelName || "text-embedding-3-small";
async embedMany(texts: string[], modelName?: string): Promise<number[][]> {
const embeddingModelName =
modelName || this.getDefaultEmbeddingModel() || "text-embedding-3-small";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/providers/openAI.ts` around lines 741 - 742, embedMany currently
hardcodes "text-embedding-3-small" instead of using the configured default;
update the function so that when modelName is falsy it calls
getDefaultEmbeddingModel() (same behavior as other embedding helpers) and uses
that result as embeddingModelName, ensuring batch embeddings honor
OPENAI_EMBEDDING_MODEL and produce the expected vector dimension; modify
embedMany to derive embeddingModelName = modelName ||
getDefaultEmbeddingModel().

Comment on lines +181 to +188
try {
const providerName = request.provider || "openai";
const provider = await ProviderFactory.createProvider(
providerName,
request.model,
);

const embedding = await provider.embed(request.text, request.model);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how withTimeout is used elsewhere in the codebase for pattern consistency
rg -n "withTimeout" --type=ts -C2

Repository: juspay/neurolink

Length of output: 27635


🏁 Script executed:

#!/bin/bash
# First, find agentRoutes.ts
fd agentRoutes.ts --type f

# Get the file size to determine how to read it
wc -l $(fd agentRoutes.ts --type f) 2>/dev/null || echo "File not found"

Repository: juspay/neurolink

Length of output: 137


🏁 Script executed:

#!/bin/bash
# Check the actual code around lines 181-188 in agentRoutes.ts
# Read the relevant section with context
sed -n '160,210p' $(fd agentRoutes.ts --type f)

Repository: juspay/neurolink

Length of output: 1567


🏁 Script executed:

#!/bin/bash
# Check ProviderFactory implementation for default provider behavior
fd ProviderFactory -t f | head -5
rg -n "createProvider" --type=ts -A 3 | grep -A 3 "default\|vertex\|openai" | head -30

Repository: juspay/neurolink

Length of output: 650


🏁 Script executed:

#!/bin/bash
# Check how other async operations are handled in agentRoutes.ts
rg -n "await" $(fd agentRoutes.ts --type f) -C 2 | head -50

Repository: juspay/neurolink

Length of output: 1457


🏁 Script executed:

#!/bin/bash
# Check ProviderFactory implementation and its default provider
fd -t f "ProviderFactory" | head -5
# Look for ProviderFactory class definition
rg -n "class ProviderFactory\|export.*ProviderFactory" --type=ts -A 10 | head -40

Repository: juspay/neurolink

Length of output: 97


🏁 Script executed:

#!/bin/bash
# Check the createProvider method to see defaults
rg -n "createProvider" --type=ts -A 8 | grep -B 2 -A 8 "vertex\|openai" | head -50

Repository: juspay/neurolink

Length of output: 1333


🏁 Script executed:

#!/bin/bash
# Check if other routes in agentRoutes.ts wrap async calls with withTimeout
grep -n "withTimeout" src/lib/server/routes/agentRoutes.ts
# Also check if they import timeout utilities
head -30 src/lib/server/routes/agentRoutes.ts

Repository: juspay/neurolink

Length of output: 762


🏁 Script executed:

#!/binbash
# Check ctx.neurolink and config structure
rg -n "ctx\.neurolink\.config\|neurolink\.config\|config\?" src/lib/server/routes/agentRoutes.ts -A 2 -B 2

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Find and inspect ProviderFactory implementation
find . -name "*providerFactory*" -type f | head -10

Repository: juspay/neurolink

Length of output: 98


🏁 Script executed:

#!/bin/bash
# Look for ProviderFactory.createProvider implementation
rg -n "export.*class ProviderFactory\|createProvider.*{" --type=ts -A 15 src/lib/factories/ | head -60

Repository: juspay/neurolink

Length of output: 219


🏁 Script executed:

#!/bin/bash
# Check what timeout utilities are available and how they're imported in routes
rg -n "import.*withTimeout\|import.*timeout" src/lib/server/routes/ --type=ts

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check other async routes to see if they wrap with withTimeout
sed -n '1,80p' src/lib/server/routes/agentRoutes.ts
sed -n '60,130p' src/lib/server/routes/agentRoutes.ts

Repository: juspay/neurolink

Length of output: 4638


🏁 Script executed:

#!/bin/bash
# Inspect ProviderFactory implementation
sed -n '1,100p' src/lib/factories/providerFactory.ts

Repository: juspay/neurolink

Length of output: 3132


🏁 Script executed:

#!/bin/bash
# Look for createProvider method in ProviderFactory
rg -n "createProvider" src/lib/factories/providerFactory.ts -A 10 | head -50

Repository: juspay/neurolink

Length of output: 898


🏁 Script executed:

#!/bin/bash
# Check if there's a default provider defined in ProviderFactory
rg -n "vertex\|openai\|default" src/lib/factories/providerFactory.ts | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check ServerContext type and config structure
rg -n "type ServerContext\|interface ServerContext" --type=ts -A 15 src/lib/server/types.ts | head -40

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check ServerContext type definition
rg -n "type ServerContext\|interface ServerContext" src/lib/server/types.ts -A 20 | head -50

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check if ctx.neurolink has config property
rg -n "neurolink.*config\|config.*timeout" src/lib/server/ --type=ts | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Verify that agentRoutes.ts doesn't use withTimeout anywhere
rg "withTimeout" src/lib/server/routes/agentRoutes.ts

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check other similar route files to see the pattern
head -40 src/lib/server/routes/*.ts | grep -E "import.*withTimeout|withTimeout"

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check how other route handlers handle async operations and timeouts
cat src/lib/server/routes/agentRoutes.ts | grep -A 30 "path: \`\${basePath\}/agent/execute\`"

Repository: juspay/neurolink

Length of output: 1015


🏁 Script executed:

#!/bin/bash
# Look for timeout configuration or defaults in server context or similar handlers
rg -n "timeout\|TIMEOUT" src/lib/server/ --type=ts | grep -i "config\|default" | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check other handlers to see if they use ctx.neurolink or similar patterns
rg -n "ctx.neurolink" src/lib/server/routes/ --type=ts -B 2 -A 2 | head -50

Repository: juspay/neurolink

Length of output: 3001


🏁 Script executed:

#!/bin/bash
# Verify the full embed handler to understand the context better
sed -n '163,209p' src/lib/server/routes/agentRoutes.ts

Repository: juspay/neurolink

Length of output: 1460


🏁 Script executed:

#!/bin/bash
# Check for any embed-specific timeout constants or patterns
rg -n "embed.*timeout\|TIMEOUT.*EMBED\|embedding.*timeout" src/ --type=ts -i | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check what timeout values are commonly used for provider operations
rg -n "30000|30_000|60000|120000" src/lib/providers/ --type=ts | head -10

Repository: juspay/neurolink

Length of output: 627


🏁 Script executed:

#!/bin/bash
# Check if there's a timeout constant or config in the server context
rg -n "type ServerContext\|interface ServerContext" src/lib/server/types.ts -A 50 | head -70

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look for ServerContext definition more thoroughly
find src/lib/server -name "*.ts" -exec grep -l "ServerContext" {} \;

Repository: juspay/neurolink

Length of output: 769


🏁 Script executed:

#!/bin/bash
# Check the server context/types definition
cat src/lib/server/types.ts | head -100

Repository: juspay/neurolink

Length of output: 2526


🏁 Script executed:

#!/bin/bash
# Look for how timeout is accessed in similar patterns in other handlers
rg -n "ctx\." src/lib/server/routes/ --type=ts -h | sort | uniq | head -30

Repository: juspay/neurolink

Length of output: 2204


🏁 Script executed:

#!/bin/bash
# Check how NeuroLink instance is created and if it has config property
rg -n "ctx.neurolink\s*=" src/lib/server/ --type=ts -B 2 -A 2 | head -40

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check NeuroLink class definition for config property
rg -n "class NeuroLink\|config.*:" src/lib/neurolink.ts | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check if other route handlers show how to get timeout from context
rg -n "timeout" src/lib/server/routes/ --type=ts | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look at the full ServerContext type definition
sed -n '200,350p' src/lib/server/types.ts

Repository: juspay/neurolink

Length of output: 3519


🏁 Script executed:

#!/bin/bash
# Check NeuroLink class to see what properties it exposes
sed -n '1,150p' src/lib/neurolink.ts

Repository: juspay/neurolink

Length of output: 4692


🏁 Script executed:

#!/bin/bash
# Search for "config" in NeuroLink class definition
rg -n "this.config\|config\s*=" src/lib/neurolink.ts | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check if config is a public property or method
rg -n "public config\|private config\|config:" src/lib/neurolink.ts | head -10

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look at the complete embed handler including error handling
sed -n '163,210p' src/lib/server/routes/agentRoutes.ts

Repository: juspay/neurolink

Length of output: 1468


🏁 Script executed:

#!/bin/bash
# Search for public properties of NeuroLink class
rg -n "^\s*(public|private|protected).*config\|get config" src/lib/neurolink.ts

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look for all public properties of NeuroLink
rg -n "^\s*(public|readonly)" src/lib/neurolink.ts | head -30

Repository: juspay/neurolink

Length of output: 93


🏁 Script executed:

#!/bin/bash
# Check if there's a way to pass timeout to embed operations
rg -n "embed.*timeout\|timeout.*embed" src/ --type=ts -B 2 -A 2 | head -40

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check embed method signature in BaseProvider
rg -n "async embed" src/lib/core/baseProvider.ts -A 5 | head -20

Repository: juspay/neurolink

Length of output: 589


🏁 Script executed:

#!/bin/bash
# Check if ServerContext has any timeout-related property
rg -n "ServerContext\|ctx\." src/lib/server/types.ts -A 2 | grep -i "timeout\|config" | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check how the server adapter passes config to routes or context
rg -n "ServerContext.*config\|createServerContext\|new ServerContext" src/lib/server/ --type=ts -A 5 | head -40

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look for any existing timeout handling in agent routes or similar handlers
rg -n "timeout\|withTimeout\|TIMEOUT" src/lib/server/routes/ --type=ts

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check the entire embedMany handler to see if it also lacks timeout
sed -n '208,250p' src/lib/server/routes/agentRoutes.ts

Repository: juspay/neurolink

Length of output: 1292


🏁 Script executed:

#!/bin/bash
# Check if there's a standard timeout value used in providers or handlers
rg -n "30000\|30_000" src/lib/ --type=ts | grep -i "embed\|const.*timeout" | head -20

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look for how other handlers get timeout values
rg -n "timeout" src/lib/server/abstract/ --type=ts -B 2 -A 2 | head -40

Repository: juspay/neurolink

Length of output: 3051


🏁 Script executed:

#!/bin/bash
# Check if NeuroLink has any internal configuration
rg -n "constructor.*config\|this.config" src/lib/neurolink.ts | head -10

Repository: juspay/neurolink

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Verify the exact lines of the embed handler one more time with full context
sed -n '160,195p' src/lib/server/routes/agentRoutes.ts

Repository: juspay/neurolink

Length of output: 1146


Wrap async provider calls with withTimeout for consistent timeout handling.

Per coding guidelines, all async operations should be wrapped with the withTimeout utility. Both ProviderFactory.createProvider and provider.embed are async calls that could hang indefinitely without timeout protection.

Additionally, the default provider "openai" (line 182) differs from ProviderFactory.createProvider's internal default of "vertex". Consider either:

  1. Omitting the default here and letting the factory decide, or
  2. Documenting this intentional override in the API docs
Proposed fix with timeout wrapper
+import { withTimeout } from "../../utils/errorHandling.js";
+
 // Inside handler:
 try {
   const providerName = request.provider || "openai";
-  const provider = await ProviderFactory.createProvider(
-    providerName,
-    request.model,
+  const provider = await withTimeout(
+    ProviderFactory.createProvider(providerName, request.model),
+    30000,
+    `Provider creation timed out`,
   );

-  const embedding = await provider.embed(request.text, request.model);
+  const embedding = await withTimeout(
+    provider.embed(request.text, request.model),
+    30000,
+    `Embedding generation timed out`,
+  );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/server/routes/agentRoutes.ts` around lines 181 - 188, Wrap the async
calls to ProviderFactory.createProvider and provider.embed with the withTimeout
utility to enforce consistent timeouts (use the same timeout value used
elsewhere or pass a configurable timeout). Update the code around
ProviderFactory.createProvider(...) and embedding via provider.embed(...) so
both calls are invoked through withTimeout(...) and properly await or catch
timeout errors. Also address the default provider mismatch by either removing
the literal default "openai" so ProviderFactory.createProvider decides the
default, or add a comment documenting the intentional override of the factory
default; reference ProviderFactory.createProvider, provider.embed, and
withTimeout when making these changes.

Comment on lines +230 to +240
try {
const providerName = request.provider || "openai";
const provider = await ProviderFactory.createProvider(
providerName,
request.model,
);

const embeddings = await provider.embedMany(
request.texts,
request.model,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Same timeout wrapper needed here.

Similar to the /embed endpoint, both ProviderFactory.createProvider and provider.embedMany calls should be wrapped with withTimeout for consistent timeout handling across the codebase. As per coding guidelines: "All async operations should be wrapped with withTimeout utility."

Proposed fix with timeout wrapper
 try {
   const providerName = request.provider || "openai";
-  const provider = await ProviderFactory.createProvider(
-    providerName,
-    request.model,
+  const provider = await withTimeout(
+    ProviderFactory.createProvider(providerName, request.model),
+    ctx.neurolink.config?.timeout ?? 30000,
+    `Provider creation timed out`,
   );

-  const embeddings = await provider.embedMany(
-    request.texts,
-    request.model,
+  const embeddings = await withTimeout(
+    provider.embedMany(request.texts, request.model),
+    ctx.neurolink.config?.timeout ?? 30000,
+    `Batch embedding generation timed out`,
   );
📝 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
try {
const providerName = request.provider || "openai";
const provider = await ProviderFactory.createProvider(
providerName,
request.model,
);
const embeddings = await provider.embedMany(
request.texts,
request.model,
);
try {
const providerName = request.provider || "openai";
const provider = await withTimeout(
ProviderFactory.createProvider(providerName, request.model),
ctx.neurolink.config?.timeout ?? 30000,
`Provider creation timed out`,
);
const embeddings = await withTimeout(
provider.embedMany(request.texts, request.model),
ctx.neurolink.config?.timeout ?? 30000,
`Batch embedding generation timed out`,
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/server/routes/agentRoutes.ts` around lines 230 - 240, Wrap the async
calls that create and use the provider with the withTimeout utility: when
obtaining providerName and calling ProviderFactory.createProvider(providerName,
request.model) wrap that Promise with withTimeout and likewise wrap
provider.embedMany(request.texts, request.model) with withTimeout so both
operations enforce the same timeout semantics; ensure you import/use the same
timeout duration or error handling pattern used by the /embed endpoint and
propagate or handle timeout errors consistently within the agentRoutes handler.

Comment on lines +127 to +140
export const EmbedRequestSchema = z.object({
text: z.string().min(1, "Text is required"),
provider: z.string().optional(),
model: z.string().optional(),
});

/**
* Embed many request schema (batch texts)
*/
export const EmbedManyRequestSchema = z.object({
texts: z
.array(z.string().min(1))
.min(1, "At least one text is required")
.max(2048, "Maximum 2048 texts per batch"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Reject whitespace-only embedding payloads.

z.string().min(1) still accepts " ", so both embedding endpoints can pass blank content through to the provider. Trim before the length check so empty/whitespace-only texts fail fast at validation time.

Suggested fix
 export const EmbedRequestSchema = z.object({
-  text: z.string().min(1, "Text is required"),
+  text: z.string().trim().min(1, "Text is required"),
   provider: z.string().optional(),
   model: z.string().optional(),
 });
 
 export const EmbedManyRequestSchema = z.object({
   texts: z
-    .array(z.string().min(1))
+    .array(z.string().trim().min(1, "Text is required"))
     .min(1, "At least one text is required")
     .max(2048, "Maximum 2048 texts per batch"),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/server/utils/validation.ts` around lines 127 - 140, The current
EmbedRequestSchema and EmbedManyRequestSchema use z.string().min(1) which allows
whitespace-only strings; update both schemas to trim input before applying the
length check so pure-whitespace texts are rejected: for EmbedRequestSchema
change the text field to trim the string (e.g., via z.string().transform(s =>
s.trim()) or use refine with s.trim()) and then apply .min(1, "Text is
required"); for EmbedManyRequestSchema update the array item schema (the z.array
element) to perform the same trim+min(1, ...) transformation so each entry is
validated after trimming while keeping the array-level .min(1, "At least one
text is required") and .max(2048, ...) intact.

Comment on lines +89 to +90
it("should create five routes", () => {
expect(routes.routes.length).toBe(5);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add handler coverage for the two new embedding routes.

Updating the route count to 5 alone will not catch regressions in POST /agent/embed and POST /agent/embed-many. The new handlers add request validation, default provider selection, and response shaping, but this file still only exercises execute, stream, and providers. Please add mocked happy-path and validation-error tests for both embedding endpoints.
As per coding guidelines, test/**/*.test.ts: Unit tests must mock external API calls; integration tests may use real API calls sparingly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/server/routes/agentRoutes.test.ts` around lines 89 - 90, Add unit
tests exercising the two new embedding routes (/agent/embed and
/agent/embed-many) rather than only updating the route count: add mocked
happy-path tests that POST to "/agent/embed" and "/agent/embed-many" asserting
the handler response shape and that the default provider selection logic runs,
and add validation-error tests that send invalid payloads and assert the
handlers return the expected validation errors. In both tests mock external API
calls used by the embed and embed-many handlers (e.g., the embedding provider
client) so they return deterministic embeddings, and place assertions on the
handler functions (embed handler names or the route paths) to confirm request
validation, provider defaulting, and response shaping behavior.

@github-actions

github-actions Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

…erver

- Add embed() and embedMany() to Google AI Studio provider with gemini-embedding-001 default
- Add embedMany() to Google Vertex, OpenAI, and Amazon Bedrock providers
- Add embedMany() base stub in BaseProvider with descriptive error for unsupported providers
- Add embed and embedMany to AIProvider type interface
- Add POST /api/agent/embed and POST /api/agent/embed-many server routes
- Add EmbedRequest, EmbedResponse, EmbedManyRequest, EmbedManyResponse server types
- Add EmbedRequestSchema and EmbedManyRequestSchema Zod validation schemas
- Replace dynamic imports of embed/embedMany with static imports from "ai" in all providers
- Update SDK API reference, server adapters guide, advanced API reference, and AIProvider docs
- Update agent routes test to account for new embedding endpoints
@github-actions

github-actions Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@sinha-sahil
sinha-sahil merged commit 17243ad into release Mar 7, 2026
17 of 18 checks passed
@sinha-sahil
sinha-sahil deleted the feat/embed-support-google-provider branch March 7, 2026 11:32
@github-actions

github-actions Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 9.18.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

This branch was successfully deployed

1 active deployment
Preview — ecaf73ec Deployed Mar 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant