movie-agent 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -6
- package/bin/movie-agent +6 -6
- package/dist/agent.d.ts +6 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +34 -17
- package/dist/agent.js.map +1 -1
- package/dist/cache.d.ts +40 -5
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +95 -11
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/factory.d.ts +4 -4
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +11 -11
- package/dist/factory.js.map +1 -1
- package/dist/format.d.ts +14 -1
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +22 -1
- package/dist/format.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +15 -4
- package/dist/llm.js.map +1 -1
- package/dist/providers.d.ts +9 -1
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +27 -0
- package/dist/providers.js.map +1 -1
- package/dist/rateLimiter.d.ts +59 -0
- package/dist/rateLimiter.d.ts.map +1 -0
- package/dist/rateLimiter.js +99 -0
- package/dist/rateLimiter.js.map +1 -0
- package/dist/sanitize.d.ts +24 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +137 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/tmdbApi.d.ts +37 -1
- package/dist/tmdbApi.d.ts.map +1 -1
- package/dist/tmdbApi.js +71 -23
- package/dist/tmdbApi.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validate.d.ts +5 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +38 -1
- package/dist/validate.js.map +1 -1
- package/package.json +6 -3
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;AAAA,oDAA4B;AAC5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAmBhB,SAAS,SAAS,CAChB,GAAW,EACX,QAAQ,GAAG,KAAK,EAChB,YAAqB;IAErB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,0CAA0C,GAAG,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,KAAK,IAAI,YAAY,CAAC;AAC/B,CAAC;AAED,MAAM,YAAY,GAAG,SAAS,CAAC,cAAc,EAAE,KAAK,EAAE,QAAQ,CAEnD,CAAC;AAEZ,MAAM,MAAM,GAAW;IACrB,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;AAAA,oDAA4B;AAC5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAmBhB,SAAS,SAAS,CAChB,GAAW,EACX,QAAQ,GAAG,KAAK,EAChB,YAAqB;IAErB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,0CAA0C,GAAG,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,KAAK,IAAI,YAAY,CAAC;AAC/B,CAAC;AAED,MAAM,YAAY,GAAG,SAAS,CAAC,cAAc,EAAE,KAAK,EAAE,QAAQ,CAEnD,CAAC;AAEZ,MAAM,MAAM,GAAW;IACrB,iBAAiB,EAAE,SAAS,CAAC,mBAAmB,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,+CAA+C;IAC/G,aAAa,EAAE,SAAS,CACtB,eAAe,EACf,KAAK,EACL,8BAA8B,CAC9B;IACF,WAAW,EAAE,SAAS,CAAC,aAAa,EAAE,KAAK,EAAE,IAAI,CAAE;IACnD,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAE,EAAE,EAAE,CAAC;IAChE,mBAAmB,EAAE,QAAQ,CAC3B,SAAS,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,CAAE,EAC7C,EAAE,CACH;IACD,mBAAmB,EAAE,QAAQ,CAC3B,SAAS,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,CAAE,EAC7C,EAAE,CACH;IAED,YAAY;IACZ,cAAc,EAAE,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,gBAAgB;IACpE,oBAAoB,EAAE,SAAS,CAAC,sBAAsB,EAAE,KAAK,CAAC;IAC9D,qBAAqB,EAAE,SAAS,CAAC,uBAAuB,EAAE,KAAK,CAAC;IAChE,uBAAuB,EAAE,SAAS,CAAC,yBAAyB,EAAE,KAAK,CAAC;IACpE,cAAc,EAAE,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC;CACnD,CAAC;AAEF,kBAAe,MAAM,CAAC"}
|
package/dist/factory.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { MovieAgent } from './agent';
|
|
|
3
3
|
* Configuration options for creating a MovieAgent instance
|
|
4
4
|
*/
|
|
5
5
|
export interface MovieAgentConfig {
|
|
6
|
-
|
|
6
|
+
tmdbAccessToken: string;
|
|
7
7
|
tmdbBaseUrl?: string;
|
|
8
8
|
tmdbRegion?: string;
|
|
9
9
|
llmProvider?: 'gemini' | 'azure';
|
|
@@ -29,7 +29,7 @@ export interface MovieAgentConfig {
|
|
|
29
29
|
* import { MovieAgentFactory } from 'movie-agent';
|
|
30
30
|
*
|
|
31
31
|
* const agent = MovieAgentFactory.create({
|
|
32
|
-
*
|
|
32
|
+
* tmdbAccessToken: process.env.TMDB_ACCESS_TOKEN,
|
|
33
33
|
* tmdbRegion: 'CA',
|
|
34
34
|
* debug: true
|
|
35
35
|
* });
|
|
@@ -57,7 +57,7 @@ export declare class MovieAgentFactory {
|
|
|
57
57
|
* environment variable names.
|
|
58
58
|
*
|
|
59
59
|
* Expected environment variables:
|
|
60
|
-
* -
|
|
60
|
+
* - TMDB_ACCESS_TOKEN (required)
|
|
61
61
|
* - TMDB_BASE_URL (optional)
|
|
62
62
|
* - TMDB_REGION (optional, defaults to 'CA')
|
|
63
63
|
* - LLM_PROVIDER (optional)
|
|
@@ -69,7 +69,7 @@ export declare class MovieAgentFactory {
|
|
|
69
69
|
*
|
|
70
70
|
* @param debug - Enable debug logging (default: false)
|
|
71
71
|
* @returns A fully configured MovieAgent instance
|
|
72
|
-
* @throws Error if
|
|
72
|
+
* @throws Error if TMDB_ACCESS_TOKEN is not set in environment
|
|
73
73
|
*
|
|
74
74
|
* @example
|
|
75
75
|
* ```typescript
|
package/dist/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAE/B,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAE/B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAG5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,iBAAiB;IAC5B;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU;IAsDnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAQ,GAAG,UAAU;CAiC1C"}
|
package/dist/factory.js
CHANGED
|
@@ -19,7 +19,7 @@ const tmdbApi_1 = __importDefault(require("./tmdbApi"));
|
|
|
19
19
|
* import { MovieAgentFactory } from 'movie-agent';
|
|
20
20
|
*
|
|
21
21
|
* const agent = MovieAgentFactory.create({
|
|
22
|
-
*
|
|
22
|
+
* tmdbAccessToken: process.env.TMDB_ACCESS_TOKEN,
|
|
23
23
|
* tmdbRegion: 'CA',
|
|
24
24
|
* debug: true
|
|
25
25
|
* });
|
|
@@ -40,11 +40,11 @@ class MovieAgentFactory {
|
|
|
40
40
|
*/
|
|
41
41
|
static create(config) {
|
|
42
42
|
// Validate required configuration
|
|
43
|
-
if (!config.
|
|
44
|
-
throw new Error('TMDB
|
|
43
|
+
if (!config.tmdbAccessToken) {
|
|
44
|
+
throw new Error('TMDB access token is required. Please provide tmdbAccessToken in the configuration.');
|
|
45
45
|
}
|
|
46
46
|
// Create TMDb API client with provided configuration
|
|
47
|
-
const tmdbClient = new tmdbApi_1.default(config.tmdbBaseUrl || 'https://api.themoviedb.org/3', config.
|
|
47
|
+
const tmdbClient = new tmdbApi_1.default(config.tmdbBaseUrl || 'https://api.themoviedb.org/3', config.tmdbAccessToken, config.tmdbRegion || 'CA');
|
|
48
48
|
// Create logger function if debug is enabled
|
|
49
49
|
const logger = config.debug
|
|
50
50
|
? (message) => console.log(`[MovieAgent] ${message}`)
|
|
@@ -72,7 +72,7 @@ class MovieAgentFactory {
|
|
|
72
72
|
enableLLM = true;
|
|
73
73
|
}
|
|
74
74
|
// Create and return MovieAgent instance
|
|
75
|
-
return new agent_1.MovieAgent(tmdbClient, logger, enableLLM, llmProvider, llmApiKey, azureConfig);
|
|
75
|
+
return new agent_1.MovieAgent(tmdbClient, logger, enableLLM, llmProvider, llmApiKey, azureConfig, config.debug);
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
78
|
* Creates a MovieAgent instance from environment variables
|
|
@@ -82,7 +82,7 @@ class MovieAgentFactory {
|
|
|
82
82
|
* environment variable names.
|
|
83
83
|
*
|
|
84
84
|
* Expected environment variables:
|
|
85
|
-
* -
|
|
85
|
+
* - TMDB_ACCESS_TOKEN (required)
|
|
86
86
|
* - TMDB_BASE_URL (optional)
|
|
87
87
|
* - TMDB_REGION (optional, defaults to 'CA')
|
|
88
88
|
* - LLM_PROVIDER (optional)
|
|
@@ -94,7 +94,7 @@ class MovieAgentFactory {
|
|
|
94
94
|
*
|
|
95
95
|
* @param debug - Enable debug logging (default: false)
|
|
96
96
|
* @returns A fully configured MovieAgent instance
|
|
97
|
-
* @throws Error if
|
|
97
|
+
* @throws Error if TMDB_ACCESS_TOKEN is not set in environment
|
|
98
98
|
*
|
|
99
99
|
* @example
|
|
100
100
|
* ```typescript
|
|
@@ -108,13 +108,13 @@ class MovieAgentFactory {
|
|
|
108
108
|
* ```
|
|
109
109
|
*/
|
|
110
110
|
static fromEnv(debug = false) {
|
|
111
|
-
const
|
|
112
|
-
if (!
|
|
113
|
-
throw new Error('
|
|
111
|
+
const tmdbAccessToken = process.env.TMDB_ACCESS_TOKEN;
|
|
112
|
+
if (!tmdbAccessToken) {
|
|
113
|
+
throw new Error('TMDB_ACCESS_TOKEN environment variable is required. ' +
|
|
114
114
|
'Please set it in your .env file or environment.');
|
|
115
115
|
}
|
|
116
116
|
return MovieAgentFactory.create({
|
|
117
|
-
|
|
117
|
+
tmdbAccessToken,
|
|
118
118
|
tmdbBaseUrl: process.env.TMDB_BASE_URL,
|
|
119
119
|
tmdbRegion: process.env.TMDB_REGION,
|
|
120
120
|
llmProvider: process.env.LLM_PROVIDER || undefined,
|
package/dist/factory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":";;;;;;AAAA,iBAAiB;AACjB,mCAAqC;AACrC,wDAAsC;AA4BtC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAa,iBAAiB;IAC5B;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,MAAwB;QACpC,kCAAkC;QAClC,IAAI,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}
|
package/dist/format.d.ts
CHANGED
|
@@ -5,9 +5,21 @@ import { MovieRecommendation, StreamingPlatform, AgentResponse, ResponseMetadata
|
|
|
5
5
|
* @returns Formatted description within word count constraints
|
|
6
6
|
*/
|
|
7
7
|
export declare function buildDescription(overview: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* TMDb image base URL for constructing poster URLs
|
|
10
|
+
* @see https://developer.themoviedb.org/docs/image-basics
|
|
11
|
+
*/
|
|
12
|
+
export declare const TMDB_IMAGE_BASE_URL = "https://image.tmdb.org/t/p/";
|
|
13
|
+
/**
|
|
14
|
+
* Builds a full poster URL from a TMDb poster_path
|
|
15
|
+
* @param posterPath - The poster_path from TMDb API (e.g., "/abc123.jpg")
|
|
16
|
+
* @param size - Image size (default: 'w500')
|
|
17
|
+
* @returns Full URL to the poster image, or null if no poster available
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildPosterUrl(posterPath: string | null | undefined, size?: string): string | null;
|
|
8
20
|
/**
|
|
9
21
|
* Formats a movie with streaming providers into a MovieRecommendation
|
|
10
|
-
* @param movie - TMDb movie object with id, title, release_date, runtime, overview, genres
|
|
22
|
+
* @param movie - TMDb movie object with id, title, release_date, runtime, overview, genres, poster_path
|
|
11
23
|
* @param providers - Streaming provider information
|
|
12
24
|
* @param reason - Why this movie was recommended
|
|
13
25
|
* @returns Formatted MovieRecommendation
|
|
@@ -22,6 +34,7 @@ export declare function toRecommendation(movie: {
|
|
|
22
34
|
id: number;
|
|
23
35
|
name: string;
|
|
24
36
|
}>;
|
|
37
|
+
poster_path?: string | null;
|
|
25
38
|
}, providers: StreamingPlatform[], reason: string): MovieRecommendation;
|
|
26
39
|
/**
|
|
27
40
|
* Formats the complete agent response with recommendations and metadata
|
package/dist/format.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuCzD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE;IACL,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuCzD;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AAEjE;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACrC,IAAI,GAAE,MAAe,GACpB,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE;IACL,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,EACD,SAAS,EAAE,iBAAiB,EAAE,EAC9B,MAAM,EAAE,MAAM,GACb,mBAAmB,CAgBrB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,eAAe,EAAE,mBAAmB,EAAE,EACtC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,cAAc,CAAC,GACpE,aAAa,CAkBf"}
|
package/dist/format.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TMDB_IMAGE_BASE_URL = void 0;
|
|
3
4
|
exports.buildDescription = buildDescription;
|
|
5
|
+
exports.buildPosterUrl = buildPosterUrl;
|
|
4
6
|
exports.toRecommendation = toRecommendation;
|
|
5
7
|
exports.formatResponse = formatResponse;
|
|
6
8
|
/**
|
|
@@ -40,9 +42,26 @@ function buildDescription(overview) {
|
|
|
40
42
|
// If we can't find a good sentence boundary, add ellipsis
|
|
41
43
|
return truncated + '...';
|
|
42
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* TMDb image base URL for constructing poster URLs
|
|
47
|
+
* @see https://developer.themoviedb.org/docs/image-basics
|
|
48
|
+
*/
|
|
49
|
+
exports.TMDB_IMAGE_BASE_URL = 'https://image.tmdb.org/t/p/';
|
|
50
|
+
/**
|
|
51
|
+
* Builds a full poster URL from a TMDb poster_path
|
|
52
|
+
* @param posterPath - The poster_path from TMDb API (e.g., "/abc123.jpg")
|
|
53
|
+
* @param size - Image size (default: 'w500')
|
|
54
|
+
* @returns Full URL to the poster image, or null if no poster available
|
|
55
|
+
*/
|
|
56
|
+
function buildPosterUrl(posterPath, size = 'w500') {
|
|
57
|
+
if (!posterPath) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return `${exports.TMDB_IMAGE_BASE_URL}${size}${posterPath}`;
|
|
61
|
+
}
|
|
43
62
|
/**
|
|
44
63
|
* Formats a movie with streaming providers into a MovieRecommendation
|
|
45
|
-
* @param movie - TMDb movie object with id, title, release_date, runtime, overview, genres
|
|
64
|
+
* @param movie - TMDb movie object with id, title, release_date, runtime, overview, genres, poster_path
|
|
46
65
|
* @param providers - Streaming provider information
|
|
47
66
|
* @param reason - Why this movie was recommended
|
|
48
67
|
* @returns Formatted MovieRecommendation
|
|
@@ -51,6 +70,7 @@ function toRecommendation(movie, providers, reason) {
|
|
|
51
70
|
const releaseYear = new Date(movie.release_date).getFullYear();
|
|
52
71
|
const description = buildDescription(movie.overview);
|
|
53
72
|
const genres = movie.genres.map(g => g.name);
|
|
73
|
+
const posterUrl = buildPosterUrl(movie.poster_path);
|
|
54
74
|
return {
|
|
55
75
|
title: movie.title,
|
|
56
76
|
releaseYear,
|
|
@@ -59,6 +79,7 @@ function toRecommendation(movie, providers, reason) {
|
|
|
59
79
|
genres,
|
|
60
80
|
streamingPlatforms: providers,
|
|
61
81
|
matchReason: reason,
|
|
82
|
+
posterUrl,
|
|
62
83
|
};
|
|
63
84
|
}
|
|
64
85
|
/**
|
package/dist/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ export { MovieAgentFactory, MovieAgentConfig } from './factory';
|
|
|
3
3
|
export { UserInput, AgentResponse, MovieRecommendation, StreamingPlatform, ErrorResponse, } from './types';
|
|
4
4
|
export { default as TmdbApiClient } from './tmdbApi';
|
|
5
5
|
export { LLMService, getLLMService } from './llm';
|
|
6
|
+
export { buildPosterUrl, TMDB_IMAGE_BASE_URL } from './format';
|
|
6
7
|
export { MovieAgentFactory as default } from './factory';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EACL,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,GACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAGlD,OAAO,EAAE,iBAAiB,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGhE,OAAO,EACL,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,GACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAGlD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG/D,OAAO,EAAE,iBAAiB,IAAI,OAAO,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.default = exports.getLLMService = exports.LLMService = exports.TmdbApiClient = exports.MovieAgentFactory = exports.MovieAgent = void 0;
|
|
7
|
+
exports.default = exports.TMDB_IMAGE_BASE_URL = exports.buildPosterUrl = exports.getLLMService = exports.LLMService = exports.TmdbApiClient = exports.MovieAgentFactory = exports.MovieAgent = void 0;
|
|
8
8
|
// Export the main MovieAgent class
|
|
9
9
|
var agent_1 = require("./agent");
|
|
10
10
|
Object.defineProperty(exports, "MovieAgent", { enumerable: true, get: function () { return agent_1.MovieAgent; } });
|
|
@@ -18,6 +18,10 @@ Object.defineProperty(exports, "TmdbApiClient", { enumerable: true, get: functio
|
|
|
18
18
|
var llm_1 = require("./llm");
|
|
19
19
|
Object.defineProperty(exports, "LLMService", { enumerable: true, get: function () { return llm_1.LLMService; } });
|
|
20
20
|
Object.defineProperty(exports, "getLLMService", { enumerable: true, get: function () { return llm_1.getLLMService; } });
|
|
21
|
+
// Export poster URL utilities
|
|
22
|
+
var format_1 = require("./format");
|
|
23
|
+
Object.defineProperty(exports, "buildPosterUrl", { enumerable: true, get: function () { return format_1.buildPosterUrl; } });
|
|
24
|
+
Object.defineProperty(exports, "TMDB_IMAGE_BASE_URL", { enumerable: true, get: function () { return format_1.TMDB_IMAGE_BASE_URL; } });
|
|
21
25
|
// Default export is the factory for convenience
|
|
22
26
|
var factory_2 = require("./factory");
|
|
23
27
|
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return factory_2.MovieAgentFactory; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,8DAA8D;;;;;;AAE9D,mCAAmC;AACnC,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AAEnB,4CAA4C;AAC5C,qCAAgE;AAAvD,4GAAA,iBAAiB,OAAA;AAW1B,gDAAgD;AAChD,qCAAqD;AAA5C,yHAAA,OAAO,OAAiB;AAEjC,4CAA4C;AAC5C,6BAAkD;AAAzC,iGAAA,UAAU,OAAA;AAAE,oGAAA,aAAa,OAAA;AAElC,gDAAgD;AAChD,qCAAyD;AAAhD,kGAAA,iBAAiB,OAAW"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,8DAA8D;;;;;;AAE9D,mCAAmC;AACnC,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AAEnB,4CAA4C;AAC5C,qCAAgE;AAAvD,4GAAA,iBAAiB,OAAA;AAW1B,gDAAgD;AAChD,qCAAqD;AAA5C,yHAAA,OAAO,OAAiB;AAEjC,4CAA4C;AAC5C,6BAAkD;AAAzC,iGAAA,UAAU,OAAA;AAAE,oGAAA,aAAa,OAAA;AAElC,8BAA8B;AAC9B,mCAA+D;AAAtD,wGAAA,cAAc,OAAA;AAAE,6GAAA,mBAAmB,OAAA;AAE5C,gDAAgD;AAChD,qCAAyD;AAAhD,kGAAA,iBAAiB,OAAW"}
|
package/dist/llm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIxC;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,KAAK,CAAM;gBAGjB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,EAC7B,WAAW,CAAC,EAAE;QACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAuEH;;;;;OAKG;IACG,qBAAqB,CACzB,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,GAAG,GACb,OAAO,CAAC,MAAM,CAAC;IA0DlB;;;;;;OAMG;IACG,2BAA2B,CAC/B,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,GAAG,EACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAC/B,OAAO,CAAC,IAAI,CAAC;IAqEhB;;OAEG;IACH,OAAO,CAAC,cAAc;CAqBvB;AAOD,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAKvE"}
|
package/dist/llm.js
CHANGED
|
@@ -11,6 +11,7 @@ const openai_1 = require("@langchain/openai");
|
|
|
11
11
|
const prompts_1 = require("@langchain/core/prompts");
|
|
12
12
|
const output_parsers_1 = require("@langchain/core/output_parsers");
|
|
13
13
|
const config_1 = __importDefault(require("./config"));
|
|
14
|
+
const sanitize_1 = require("./sanitize");
|
|
14
15
|
/**
|
|
15
16
|
* LLM service for generating formatted movie recommendation output
|
|
16
17
|
*/
|
|
@@ -98,8 +99,13 @@ ${index + 1}. ${movie.title} (${movie.releaseYear})
|
|
|
98
99
|
`;
|
|
99
100
|
})
|
|
100
101
|
.join('\n');
|
|
101
|
-
//
|
|
102
|
-
const
|
|
102
|
+
// Sanitize and format user input to prevent prompt injection
|
|
103
|
+
const sanitizedInput = (0, sanitize_1.sanitizeForLLMPrompt)(userInput);
|
|
104
|
+
// Log potential injection attempts for security monitoring
|
|
105
|
+
if ((0, sanitize_1.detectPromptInjection)(userInput)) {
|
|
106
|
+
console.warn('⚠️ Potential prompt injection detected in user input. Input has been sanitized.');
|
|
107
|
+
}
|
|
108
|
+
const userInputText = JSON.stringify(sanitizedInput, null, 2);
|
|
103
109
|
// Generate formatted output using LLM with timeout
|
|
104
110
|
try {
|
|
105
111
|
const timeoutMs = 15000; // 15 second timeout
|
|
@@ -146,8 +152,13 @@ ${index + 1}. ${movie.title} (${movie.releaseYear})
|
|
|
146
152
|
`;
|
|
147
153
|
})
|
|
148
154
|
.join('\n');
|
|
149
|
-
//
|
|
150
|
-
const
|
|
155
|
+
// Sanitize and format user input to prevent prompt injection
|
|
156
|
+
const sanitizedInput = (0, sanitize_1.sanitizeForLLMPrompt)(userInput);
|
|
157
|
+
// Log potential injection attempts for security monitoring
|
|
158
|
+
if ((0, sanitize_1.detectPromptInjection)(userInput)) {
|
|
159
|
+
console.warn('⚠️ Potential prompt injection detected in user input. Input has been sanitized.');
|
|
160
|
+
}
|
|
161
|
+
const userInputText = JSON.stringify(sanitizedInput, null, 2);
|
|
151
162
|
try {
|
|
152
163
|
const timeoutMs = 15000; // 15 second timeout
|
|
153
164
|
const startTime = Date.now();
|
package/dist/llm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
|
package/dist/providers.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import TmdbApiClient from './tmdbApi';
|
|
1
|
+
import TmdbApiClient, { WatchProvidersResponse } from './tmdbApi';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts and normalizes platform names from a WatchProvidersResponse.
|
|
4
|
+
* This is used when watch providers are fetched via append_to_response.
|
|
5
|
+
* @param providersData WatchProvidersResponse data (can be from append_to_response)
|
|
6
|
+
* @param region Region code (default: "CA")
|
|
7
|
+
* @returns Array of normalized platform names
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractPlatformsFromProviders(providersData: WatchProvidersResponse | undefined, region?: string): string[];
|
|
2
10
|
/**
|
|
3
11
|
* Fetch and normalize Canadian watch providers for a movie.
|
|
4
12
|
* @param movieId TMDb movie ID
|
package/dist/providers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AACA,OAAO,aAAa,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AACA,OAAO,aAAa,EAAE,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAmBlE;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,sBAAsB,GAAG,SAAS,EACjD,MAAM,SAAO,GACZ,MAAM,EAAE,CAoBV;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,MAAM,SAAO,EACb,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,EAAE,CAAC,CAwCnB"}
|
package/dist/providers.js
CHANGED
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.extractPlatformsFromProviders = extractPlatformsFromProviders;
|
|
6
7
|
exports.getCanadianProviders = getCanadianProviders;
|
|
7
8
|
// src/providers.ts
|
|
8
9
|
const tmdbApi_1 = __importDefault(require("./tmdbApi"));
|
|
@@ -22,6 +23,32 @@ const PLATFORM_MAP = {
|
|
|
22
23
|
fuboTV: 'fuboTV',
|
|
23
24
|
// Add more mappings as needed
|
|
24
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Extracts and normalizes platform names from a WatchProvidersResponse.
|
|
28
|
+
* This is used when watch providers are fetched via append_to_response.
|
|
29
|
+
* @param providersData WatchProvidersResponse data (can be from append_to_response)
|
|
30
|
+
* @param region Region code (default: "CA")
|
|
31
|
+
* @returns Array of normalized platform names
|
|
32
|
+
*/
|
|
33
|
+
function extractPlatformsFromProviders(providersData, region = 'CA') {
|
|
34
|
+
if (!providersData ||
|
|
35
|
+
!providersData.results ||
|
|
36
|
+
!providersData.results[region]) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
const regionData = providersData.results[region];
|
|
40
|
+
// Only consider 'flatrate' (subscription) providers
|
|
41
|
+
const flatrate = regionData.flatrate || [];
|
|
42
|
+
if (!Array.isArray(flatrate) || flatrate.length === 0) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
// Map provider names to allowed platforms
|
|
46
|
+
const platforms = flatrate
|
|
47
|
+
.map((p) => PLATFORM_MAP[p.provider_name])
|
|
48
|
+
.filter(Boolean);
|
|
49
|
+
// Remove duplicates
|
|
50
|
+
return Array.from(new Set(platforms));
|
|
51
|
+
}
|
|
25
52
|
/**
|
|
26
53
|
* Fetch and normalize Canadian watch providers for a movie.
|
|
27
54
|
* @param movieId TMDb movie ID
|
package/dist/providers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":";;;;;AA2BA,oDA4CC;
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":";;;;;AA2BA,sEAuBC;AASD,oDA4CC;AAvGD,mBAAmB;AACnB,wDAAkE;AAClE,mCAA8D;AAC9D,sDAA8B;AAE9B,iDAAiD;AACjD,MAAM,YAAY,GAA2B;IAC3C,OAAO,EAAE,SAAS;IAClB,oBAAoB,EAAE,aAAa;IACnC,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,OAAO;IACd,eAAe,EAAE,WAAW;IAC5B,gBAAgB,EAAE,YAAY;IAC9B,SAAS,EAAE,SAAS;IACpB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,8BAA8B;CAC/B,CAAC;AAEF;;;;;;GAMG;AACH,SAAgB,6BAA6B,CAC3C,aAAiD,EACjD,MAAM,GAAG,IAAI;IAEb,IACE,CAAC,aAAa;QACd,CAAC,aAAa,CAAC,OAAO;QACtB,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,EAC9B,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,oDAAoD;IACpD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,0CAA0C;IAC1C,MAAM,SAAS,GAAG,QAAQ;SACvB,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;SAC9C,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,oBAAoB;IACpB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,oBAAoB,CACxC,OAAwB,EACxB,MAAM,GAAG,IAAI,EACb,MAAsB;IAEtB,IAAI,CAAC;QACH,oBAAoB;QACpB,MAAM,KAAK,GAAG,IAAA,gBAAQ,EAAC,gBAAM,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAA,iCAAyB,EAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5D,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAW,QAAQ,CAAC,CAAC;QAEnD,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,8BAA8B;QAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,IAAI,iBAAa,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,iDAAiD;YACjD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACxB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACxC,oDAAoD;QACpD,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACxB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,0CAA0C;QAC1C,MAAM,SAAS,GAAG,QAAQ;aACvB,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;aAC9C,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,oBAAoB;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QAE9C,iBAAiB;QACjB,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE5B,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import pLimit from 'p-limit';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for rate limiting
|
|
4
|
+
*/
|
|
5
|
+
export interface RateLimiterConfig {
|
|
6
|
+
/** Maximum concurrent requests (default: 10) */
|
|
7
|
+
concurrency: number;
|
|
8
|
+
/** Maximum retry attempts for rate limit errors (default: 3) */
|
|
9
|
+
maxRetries: number;
|
|
10
|
+
/** Base delay in milliseconds for exponential backoff (default: 1000) */
|
|
11
|
+
baseDelayMs: number;
|
|
12
|
+
/** Maximum delay in milliseconds for exponential backoff (default: 30000) */
|
|
13
|
+
maxDelayMs: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Default rate limiter configuration
|
|
17
|
+
* TMDb allows 40 requests per 10 seconds, so we limit to 10 concurrent requests
|
|
18
|
+
* to stay well under the limit
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_RATE_LIMITER_CONFIG: RateLimiterConfig;
|
|
21
|
+
/**
|
|
22
|
+
* Rate limiter instance type
|
|
23
|
+
*/
|
|
24
|
+
export type RateLimiter = ReturnType<typeof pLimit>;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a rate limiter with the specified concurrency
|
|
27
|
+
* @param concurrency - Maximum number of concurrent operations
|
|
28
|
+
* @returns A rate limiter function
|
|
29
|
+
*/
|
|
30
|
+
export declare function createRateLimiter(concurrency?: number): RateLimiter;
|
|
31
|
+
/**
|
|
32
|
+
* Calculates exponential backoff delay with jitter
|
|
33
|
+
* @param attempt - Current retry attempt (0-based)
|
|
34
|
+
* @param baseDelayMs - Base delay in milliseconds
|
|
35
|
+
* @param maxDelayMs - Maximum delay cap in milliseconds
|
|
36
|
+
* @returns Delay in milliseconds
|
|
37
|
+
*/
|
|
38
|
+
export declare function calculateBackoffDelay(attempt: number, baseDelayMs?: number, maxDelayMs?: number): number;
|
|
39
|
+
/**
|
|
40
|
+
* Delays execution for the specified duration
|
|
41
|
+
* @param ms - Delay in milliseconds
|
|
42
|
+
* @returns Promise that resolves after the delay
|
|
43
|
+
*/
|
|
44
|
+
export declare function delay(ms: number): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Checks if an error is a rate limit error (HTTP 429)
|
|
47
|
+
* @param error - The error to check
|
|
48
|
+
* @returns True if the error is a rate limit error
|
|
49
|
+
*/
|
|
50
|
+
export declare function isRateLimitError(error: unknown): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Executes an async function with exponential backoff retry on rate limit errors
|
|
53
|
+
* @param fn - The async function to execute
|
|
54
|
+
* @param config - Rate limiter configuration
|
|
55
|
+
* @returns Promise resolving to the function result
|
|
56
|
+
* @throws The last error if all retries are exhausted
|
|
57
|
+
*/
|
|
58
|
+
export declare function withRetry<T>(fn: () => Promise<T>, config?: Partial<RateLimiterConfig>): Promise<T>;
|
|
59
|
+
//# sourceMappingURL=rateLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimiter.d.ts","sourceRoot":"","sources":["../src/rateLimiter.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,SAAS,CAAC;AAE7B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,iBAKzC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,GAAE,MAAgD,GAC5D,WAAW,CAEb;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,MAAgD,EAC7D,UAAU,GAAE,MAA+C,GAC1D,MAAM,CAOR;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAOxD;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,OAAO,CAAC,iBAAiB,CAAM,GACtC,OAAO,CAAC,CAAC,CAAC,CA4BZ"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_RATE_LIMITER_CONFIG = void 0;
|
|
7
|
+
exports.createRateLimiter = createRateLimiter;
|
|
8
|
+
exports.calculateBackoffDelay = calculateBackoffDelay;
|
|
9
|
+
exports.delay = delay;
|
|
10
|
+
exports.isRateLimitError = isRateLimitError;
|
|
11
|
+
exports.withRetry = withRetry;
|
|
12
|
+
// src/rateLimiter.ts
|
|
13
|
+
const p_limit_1 = __importDefault(require("p-limit"));
|
|
14
|
+
/**
|
|
15
|
+
* Default rate limiter configuration
|
|
16
|
+
* TMDb allows 40 requests per 10 seconds, so we limit to 10 concurrent requests
|
|
17
|
+
* to stay well under the limit
|
|
18
|
+
*/
|
|
19
|
+
exports.DEFAULT_RATE_LIMITER_CONFIG = {
|
|
20
|
+
concurrency: 10,
|
|
21
|
+
maxRetries: 3,
|
|
22
|
+
baseDelayMs: 1000,
|
|
23
|
+
maxDelayMs: 30000,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Creates a rate limiter with the specified concurrency
|
|
27
|
+
* @param concurrency - Maximum number of concurrent operations
|
|
28
|
+
* @returns A rate limiter function
|
|
29
|
+
*/
|
|
30
|
+
function createRateLimiter(concurrency = exports.DEFAULT_RATE_LIMITER_CONFIG.concurrency) {
|
|
31
|
+
return (0, p_limit_1.default)(concurrency);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Calculates exponential backoff delay with jitter
|
|
35
|
+
* @param attempt - Current retry attempt (0-based)
|
|
36
|
+
* @param baseDelayMs - Base delay in milliseconds
|
|
37
|
+
* @param maxDelayMs - Maximum delay cap in milliseconds
|
|
38
|
+
* @returns Delay in milliseconds
|
|
39
|
+
*/
|
|
40
|
+
function calculateBackoffDelay(attempt, baseDelayMs = exports.DEFAULT_RATE_LIMITER_CONFIG.baseDelayMs, maxDelayMs = exports.DEFAULT_RATE_LIMITER_CONFIG.maxDelayMs) {
|
|
41
|
+
// Exponential backoff: baseDelay * 2^attempt
|
|
42
|
+
const exponentialDelay = baseDelayMs * Math.pow(2, attempt);
|
|
43
|
+
// Add jitter (0-25% of the delay) to avoid thundering herd
|
|
44
|
+
const jitter = exponentialDelay * Math.random() * 0.25;
|
|
45
|
+
// Cap at maxDelayMs
|
|
46
|
+
return Math.min(exponentialDelay + jitter, maxDelayMs);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Delays execution for the specified duration
|
|
50
|
+
* @param ms - Delay in milliseconds
|
|
51
|
+
* @returns Promise that resolves after the delay
|
|
52
|
+
*/
|
|
53
|
+
function delay(ms) {
|
|
54
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Checks if an error is a rate limit error (HTTP 429)
|
|
58
|
+
* @param error - The error to check
|
|
59
|
+
* @returns True if the error is a rate limit error
|
|
60
|
+
*/
|
|
61
|
+
function isRateLimitError(error) {
|
|
62
|
+
if (error instanceof Error) {
|
|
63
|
+
return (error.message.includes('429') || error.message.includes('rate limit'));
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Executes an async function with exponential backoff retry on rate limit errors
|
|
69
|
+
* @param fn - The async function to execute
|
|
70
|
+
* @param config - Rate limiter configuration
|
|
71
|
+
* @returns Promise resolving to the function result
|
|
72
|
+
* @throws The last error if all retries are exhausted
|
|
73
|
+
*/
|
|
74
|
+
async function withRetry(fn, config = {}) {
|
|
75
|
+
const { maxRetries, baseDelayMs, maxDelayMs } = {
|
|
76
|
+
...exports.DEFAULT_RATE_LIMITER_CONFIG,
|
|
77
|
+
...config,
|
|
78
|
+
};
|
|
79
|
+
let lastError;
|
|
80
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
81
|
+
try {
|
|
82
|
+
return await fn();
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
lastError = error;
|
|
86
|
+
// Only retry on rate limit errors
|
|
87
|
+
if (!isRateLimitError(error)) {
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
// Don't delay after the last attempt
|
|
91
|
+
if (attempt < maxRetries) {
|
|
92
|
+
const delayMs = calculateBackoffDelay(attempt, baseDelayMs, maxDelayMs);
|
|
93
|
+
await delay(delayMs);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw lastError;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=rateLimiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../src/rateLimiter.ts"],"names":[],"mappings":";;;;;;AAuCA,8CAIC;AASD,sDAWC;AAOD,sBAEC;AAOD,4CAOC;AASD,8BA+BC;AA9HD,qBAAqB;AACrB,sDAA6B;AAgB7B;;;;GAIG;AACU,QAAA,2BAA2B,GAAsB;IAC5D,WAAW,EAAE,EAAE;IACf,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,KAAK;CAClB,CAAC;AAOF;;;;GAIG;AACH,SAAgB,iBAAiB,CAC/B,cAAsB,mCAA2B,CAAC,WAAW;IAE7D,OAAO,IAAA,iBAAM,EAAC,WAAW,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,qBAAqB,CACnC,OAAe,EACf,cAAsB,mCAA2B,CAAC,WAAW,EAC7D,aAAqB,mCAA2B,CAAC,UAAU;IAE3D,6CAA6C;IAC7C,MAAM,gBAAgB,GAAG,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC5D,2DAA2D;IAC3D,MAAM,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;IACvD,oBAAoB;IACpB,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,GAAG,MAAM,EAAE,UAAU,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,SAAgB,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,KAAc;IAC7C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,SAAqC,EAAE;IAEvC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG;QAC9C,GAAG,mCAA2B;QAC9B,GAAG,MAAM;KACV,CAAC;IAEF,IAAI,SAAkB,CAAC;IAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAElB,kCAAkC;YAClC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7B,MAAM,KAAK,CAAC;YACd,CAAC;YAED,qCAAqC;YACrC,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;gBACxE,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,SAAS,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes user input to prevent prompt injection attacks
|
|
3
|
+
* This is specifically for content that will be passed to LLM prompts
|
|
4
|
+
*
|
|
5
|
+
* @param input - Raw user input object
|
|
6
|
+
* @returns Sanitized version safe for LLM prompts
|
|
7
|
+
*/
|
|
8
|
+
export declare function sanitizeForLLMPrompt(input: any): any;
|
|
9
|
+
/**
|
|
10
|
+
* Sanitizes a string to remove potential prompt injection attacks
|
|
11
|
+
*
|
|
12
|
+
* @param str - Input string to sanitize
|
|
13
|
+
* @returns Sanitized string
|
|
14
|
+
*/
|
|
15
|
+
export declare function sanitizeString(str: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Detects if input contains potential prompt injection attempts
|
|
18
|
+
* This is for logging/monitoring purposes
|
|
19
|
+
*
|
|
20
|
+
* @param input - Input to check
|
|
21
|
+
* @returns True if potential injection detected
|
|
22
|
+
*/
|
|
23
|
+
export declare function detectPromptInjection(input: any): boolean;
|
|
24
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AA4BA;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG,CA+BpD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA4ClD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CA6BzD"}
|