Skip to content

Add retry logic, caching, streaming progress, and model comparison features - #617

Open
thebigdog47 wants to merge 1 commit into
lmstudio-ai:mainfrom
thebigdog47:thebigdog47-add-retry-caching-streaming-comparison
Open

Add retry logic, caching, streaming progress, and model comparison features#617
thebigdog47 wants to merge 1 commit into
lmstudio-ai:mainfrom
thebigdog47:thebigdog47-add-retry-caching-streaming-comparison

Conversation

@thebigdog47

Copy link
Copy Markdown

Overview

This PR adds four major feature enhancements to the lmstudio-js SDK to improve reliability, performance, and usability. These features are designed to work independently but complement each other when used together.

Changes

1. Enhanced Error Handling & Retry Logic

  • New module: packages/lms-common/src/retryPolicy.ts
  • Exponential backoff with configurable jitter for transient error recovery
  • Predefined retry policies (aggressive, balanced, conservative, none)
  • Smart error classification to distinguish retryable vs non-retryable errors
  • Integrated into ClientPort.callRpc() for automatic RPC retry support
  • Callback hooks for monitoring retry attempts

2. Model Caching Layer

  • New module: packages/lms-client/src/cache/ModelMetadataCache.ts
  • TTL-based cache with automatic expiration
  • Max entries limit with LRU eviction strategy
  • Cache statistics and invalidation methods
  • getOrCompute() for lazy loading with automatic caching
  • CacheManager for managing multiple named caches

3. Streaming Response Progress

  • New module: packages/lms-client/src/streaming/ProgressTracker.ts
  • Real-time progress tracking for streaming responses
  • Token counting and chunk tracking with progress callbacks
  • Performance metrics: tokens/second, time remaining estimation
  • Completion and error handlers
  • Console progress helper for easy integration

4. Model Comparison Tools

  • New module: packages/lms-client/src/tools/ModelComparison.ts
  • Multi-model comparison with identical inputs
  • Comprehensive metrics collection: latency, token output, success/failure
  • Timeout handling for long-running models
  • Export results in multiple formats (formatted text, JSON, CSV)
  • Statistical analysis: fastest, slowest, average latency

Implementation Details

Quality & Testing

  • 53 comprehensive test cases across all features
  • Full coverage of happy paths, error handling, and edge cases
  • Integration test patterns included

Documentation

  • FEATURES_GUIDE.md: Complete feature documentation with usage examples
  • Predefined policies and configuration best practices
  • Integration patterns showing how features work together
  • API reference for all new classes and functions

Integration Points

  • Modified packages/lms-communication-client/src/ClientPort.ts to support retry policies
  • Updated packages/lms-common/src/index.ts to export new retry utilities
  • All changes are backward compatible; retry is enabled by default with balanced policy

Files Changed

  • 7 new feature/tool modules
  • 4 comprehensive test files
  • 1 detailed guide document
  • 2 modified files for integration

Total: 2,518 lines added (features, tests, documentation)

…omparison features

Add four major feature enhancements to the SDK:

1. Enhanced Error Handling & Retry Logic
   - Add retry policy system with exponential backoff
   - Support configurable retry strategies
   - Provide predefined retry policies (aggressive, balanced, conservative, none)
   - Integrate retry logic into ClientPort RPC calls

2. Model Caching Layer
   - Create ModelMetadataCache with TTL and max entries
   - Implement CacheManager for multiple named caches
   - Add cache statistics and invalidation methods
   - Support lazy loading with getOrCompute

3. Streaming Response Progress
   - Add StreamingProgressTracker for token/chunk tracking
   - Implement progress callbacks with throttling
   - Calculate token rate and time estimates
   - Support completion and error handlers

4. Model Comparison Tools
   - Create ModelComparisonRunner for multi-model testing
   - Collect comprehensive performance metrics
   - Support multiple export formats (text, JSON, CSV)
   - Handle timeouts and failures gracefully

Includes comprehensive test suites for all features and detailed documentation
with usage examples and best practices.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


GitHub Copilot seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff2bd63ba9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread FEATURES_GUIDE.md

#### Basic Usage
```typescript
import { LMStudioClient, predefinedRetryPolicies } from "@lmstudio/sdk";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Export the documented SDK APIs

The guide tells users to import predefinedRetryPolicies from @lmstudio/sdk, and later does the same for the new cache/progress/comparison APIs, but publish/sdk/src/index.ts does not re-export any of these symbols and packages/lms-client/src/index.ts does not export the new client modules either. In the published package these examples fail at compile time; additionally LMStudioClient's strict constructor schema has no retryPolicy option, so this documented configuration cannot be used through the SDK entry point.

Useful? React with 👍 / 👎.

const response = await Promise.race([
respond(config.input),
new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error("Model timeout")), config.timeoutMs ?? 30000),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear comparison timeout timers

When respond(config.input) resolves before the timeout, the setTimeout created here is never cleared. A successful comparison in a short-lived CLI/script will keep the Node event loop alive until every pending timeout fires (30s by default, or timeoutMs per model), even though compare() has already returned.

Useful? React with 👍 / 👎.

Comment on lines +199 to +201
const fastest = successfulMetrics.reduce((prev, current) =>
prev.latencyMs < current.latencyMs ? prev : current,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle all-failure comparisons without throwing

If every model rejects or times out (or the input model list is empty), successfulMetrics is empty and this reduce throws before a ModelComparisonResult can be returned. That breaks the advertised failure-handling path because callers lose the collected failure metrics instead of receiving a result with successCount: 0.

Useful? React with 👍 / 👎.

Comment on lines +101 to +103
if (config.useJitter) {
const jitter = delay * Math.random();
delay = delay + jitter;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Cap jittered delays at maxDelayMs

The delay is capped before jitter, then jitter adds up to another full delay on top of that. With the default useJitter: true, a policy with maxDelayMs: 10000 can sleep for almost 20 seconds, which violates the documented maximum delay and makes the predefined policy caps unreliable.

Useful? React with 👍 / 👎.

public reset(): void {
this.tokenCount = 0;
this.content = "";
this.lastUpdateTime = Date.now();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reset the progress start time

After reset() is used to reuse a tracker, tokenCount and content are cleared but the immutable startTime remains the original constructor time. The next stream's getProgress() and complete() therefore include all idle time before the reset, overstating elapsed time and underreporting tokens/sec.

Useful? React with 👍 / 👎.

@thebigdog47

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@thebigdog47

Copy link
Copy Markdown
Author

recheck

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