movie-agent 1.0.0
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/LICENSE +21 -0
- package/README.md +464 -0
- package/bin/movie-agent +209 -0
- package/dist/agent.d.ts +89 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +365 -0
- package/dist/agent.js.map +1 -0
- package/dist/cache.d.ts +75 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +133 -0
- package/dist/cache.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +31 -0
- package/dist/config.js.map +1 -0
- package/dist/discover.d.ts +38 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +121 -0
- package/dist/discover.js.map +1 -0
- package/dist/factory.d.ts +87 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +118 -0
- package/dist/factory.js.map +1 -0
- package/dist/filters.d.ts +61 -0
- package/dist/filters.d.ts.map +1 -0
- package/dist/filters.js +97 -0
- package/dist/filters.js.map +1 -0
- package/dist/format.d.ts +33 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +85 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/mood.d.ts +7 -0
- package/dist/mood.d.ts.map +1 -0
- package/dist/mood.js +21 -0
- package/dist/mood.js.map +1 -0
- package/dist/providers.d.ts +10 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +70 -0
- package/dist/providers.js.map +1 -0
- package/dist/ranking.d.ts +57 -0
- package/dist/ranking.d.ts.map +1 -0
- package/dist/ranking.js +198 -0
- package/dist/ranking.js.map +1 -0
- package/dist/tmdbApi.d.ts +79 -0
- package/dist/tmdbApi.d.ts.map +1 -0
- package/dist/tmdbApi.js +88 -0
- package/dist/tmdbApi.js.map +1 -0
- package/dist/types.d.ts +99 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +13 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +47 -0
- package/dist/validate.js.map +1 -0
- package/package.json +72 -0
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { UserInput, AgentResponse, ErrorResponse } from './types';
|
|
2
|
+
import TmdbApiClient from './tmdbApi';
|
|
3
|
+
/**
|
|
4
|
+
* MovieAgent orchestrates the full recommendation pipeline
|
|
5
|
+
*/
|
|
6
|
+
export declare class MovieAgent {
|
|
7
|
+
private tmdbClient;
|
|
8
|
+
private logger;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new MovieAgent instance
|
|
11
|
+
* @param tmdbClient - Optional TMDb API client for testing
|
|
12
|
+
* @param logger - Optional logger function for debugging
|
|
13
|
+
*/
|
|
14
|
+
constructor(tmdbClient?: TmdbApiClient, logger?: (message: string) => void);
|
|
15
|
+
/**
|
|
16
|
+
* Gets movie recommendations based on user input
|
|
17
|
+
* @param input - User input with mood, platforms, genres, runtime, and year preferences
|
|
18
|
+
* @returns Promise resolving to structured agent response with 3-5 recommendations or error response
|
|
19
|
+
*/
|
|
20
|
+
getRecommendations(input: UserInput): Promise<AgentResponse | ErrorResponse>;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a structured error response
|
|
23
|
+
* @param errorType - The type of error
|
|
24
|
+
* @param message - Human-readable error message
|
|
25
|
+
* @param details - Optional details for debugging
|
|
26
|
+
* @returns ErrorResponse object
|
|
27
|
+
*/
|
|
28
|
+
private createErrorResponse;
|
|
29
|
+
/**
|
|
30
|
+
* Handles errors and converts them to structured error responses
|
|
31
|
+
* @param error - The error to handle
|
|
32
|
+
* @returns ErrorResponse object
|
|
33
|
+
*/
|
|
34
|
+
private handleError;
|
|
35
|
+
/**
|
|
36
|
+
* Validates user input
|
|
37
|
+
* @param input - User input to validate
|
|
38
|
+
* @throws Error if validation fails
|
|
39
|
+
*/
|
|
40
|
+
private validateInput;
|
|
41
|
+
/**
|
|
42
|
+
* Resolves genres from mood or explicit genre input
|
|
43
|
+
* @param input - User input
|
|
44
|
+
* @returns Array of genre names
|
|
45
|
+
*/
|
|
46
|
+
private resolveGenres;
|
|
47
|
+
/**
|
|
48
|
+
* Discovers candidate movies from TMDb
|
|
49
|
+
* @param input - User input
|
|
50
|
+
* @param genres - Resolved genres
|
|
51
|
+
* @returns Array of movie summaries
|
|
52
|
+
*/
|
|
53
|
+
private discoverCandidates;
|
|
54
|
+
/**
|
|
55
|
+
* Fetches watch providers for each candidate movie
|
|
56
|
+
* @param candidates - Array of movie details
|
|
57
|
+
* @returns Array of movies with platform information
|
|
58
|
+
*/
|
|
59
|
+
private fetchWatchProviders;
|
|
60
|
+
/**
|
|
61
|
+
* Applies user-specified filters to movies
|
|
62
|
+
* @param movies - Movies with provider information
|
|
63
|
+
* @param input - User input
|
|
64
|
+
* @returns Filtered movies
|
|
65
|
+
*/
|
|
66
|
+
private applyFilters;
|
|
67
|
+
/**
|
|
68
|
+
* Ranks movies and selects top 3-5
|
|
69
|
+
* @param movies - Filtered movies
|
|
70
|
+
* @param input - User input
|
|
71
|
+
* @returns Top 3-5 movies
|
|
72
|
+
*/
|
|
73
|
+
private rankAndSelect;
|
|
74
|
+
/**
|
|
75
|
+
* Formats movies into recommendations
|
|
76
|
+
* @param movies - Selected movies
|
|
77
|
+
* @param input - User input
|
|
78
|
+
* @returns Array of formatted recommendations
|
|
79
|
+
*/
|
|
80
|
+
private formatRecommendations;
|
|
81
|
+
/**
|
|
82
|
+
* Generates a match reason for a movie
|
|
83
|
+
* @param movie - Movie to explain
|
|
84
|
+
* @param input - User input
|
|
85
|
+
* @returns Match reason string
|
|
86
|
+
*/
|
|
87
|
+
private generateMatchReason;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,aAAa,EAGb,aAAa,EACd,MAAM,SAAS,CAAC;AASjB,OAAO,aAA+B,MAAM,WAAW,CAAC;AAaxD;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,MAAM,CAA4B;IAE1C;;;;OAIG;gBACS,UAAU,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAM1E;;;;OAIG;IACG,kBAAkB,CACtB,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC;IAgEzC;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAc3B;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAmEnB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAqBrB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAerB;;;;;OAKG;YACW,kBAAkB;IA0ChC;;;;OAIG;YACW,mBAAmB;IAgCjC;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IA+BpB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAoCrB;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAiC7B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;CAuC5B"}
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
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.MovieAgent = void 0;
|
|
7
|
+
const validate_1 = require("./validate");
|
|
8
|
+
const mood_1 = require("./mood");
|
|
9
|
+
const discover_1 = require("./discover");
|
|
10
|
+
const tmdbApi_1 = __importDefault(require("./tmdbApi"));
|
|
11
|
+
const providers_1 = require("./providers");
|
|
12
|
+
const filters_1 = require("./filters");
|
|
13
|
+
const ranking_1 = require("./ranking");
|
|
14
|
+
const format_1 = require("./format");
|
|
15
|
+
/**
|
|
16
|
+
* MovieAgent orchestrates the full recommendation pipeline
|
|
17
|
+
*/
|
|
18
|
+
class MovieAgent {
|
|
19
|
+
/**
|
|
20
|
+
* Creates a new MovieAgent instance
|
|
21
|
+
* @param tmdbClient - Optional TMDb API client for testing
|
|
22
|
+
* @param logger - Optional logger function for debugging
|
|
23
|
+
*/
|
|
24
|
+
constructor(tmdbClient, logger) {
|
|
25
|
+
this.tmdbClient = tmdbClient ?? new tmdbApi_1.default();
|
|
26
|
+
this.logger =
|
|
27
|
+
logger ?? ((message) => console.log(`[MovieAgent] ${message}`));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Gets movie recommendations based on user input
|
|
31
|
+
* @param input - User input with mood, platforms, genres, runtime, and year preferences
|
|
32
|
+
* @returns Promise resolving to structured agent response with 3-5 recommendations or error response
|
|
33
|
+
*/
|
|
34
|
+
async getRecommendations(input) {
|
|
35
|
+
try {
|
|
36
|
+
this.logger('Starting recommendation pipeline');
|
|
37
|
+
// Step 1: Validate input
|
|
38
|
+
this.logger('Step 1: Validating input');
|
|
39
|
+
this.validateInput(input);
|
|
40
|
+
// Step 2: Resolve genres from mood or explicit input
|
|
41
|
+
this.logger('Step 2: Resolving genres');
|
|
42
|
+
const genres = this.resolveGenres(input);
|
|
43
|
+
this.logger(`Resolved genres: ${genres.join(', ')}`);
|
|
44
|
+
// Step 3: Discover candidate movies via TMDb
|
|
45
|
+
this.logger('Step 3: Discovering candidate movies');
|
|
46
|
+
const candidates = await this.discoverCandidates(input, genres);
|
|
47
|
+
this.logger(`Found ${candidates.length} candidate movies`);
|
|
48
|
+
if (candidates.length === 0) {
|
|
49
|
+
return this.createErrorResponse('NO_RESULTS', 'No movies found matching the criteria');
|
|
50
|
+
}
|
|
51
|
+
// Step 4: Fetch watch providers for each candidate (region CA)
|
|
52
|
+
this.logger('Step 4: Fetching watch providers');
|
|
53
|
+
const moviesWithProviders = await this.fetchWatchProviders(candidates);
|
|
54
|
+
this.logger(`Fetched providers for ${moviesWithProviders.length} movies`);
|
|
55
|
+
// Step 5: Apply filters (platforms, runtime, year)
|
|
56
|
+
this.logger('Step 5: Applying filters');
|
|
57
|
+
const filtered = this.applyFilters(moviesWithProviders, input);
|
|
58
|
+
this.logger(`${filtered.length} movies passed filters`);
|
|
59
|
+
if (filtered.length === 0) {
|
|
60
|
+
return this.createErrorResponse('NO_RESULTS', 'No movies match the specified filters (platforms, runtime, year)');
|
|
61
|
+
}
|
|
62
|
+
// Step 6: Rank and select top 3-5 movies
|
|
63
|
+
this.logger('Step 6: Ranking and selecting top movies');
|
|
64
|
+
const topMovies = this.rankAndSelect(filtered, input);
|
|
65
|
+
this.logger(`Selected ${topMovies.length} top movies`);
|
|
66
|
+
// Step 7: Format structured output with metadata
|
|
67
|
+
this.logger('Step 7: Formatting output');
|
|
68
|
+
const recommendations = this.formatRecommendations(topMovies, input);
|
|
69
|
+
const response = (0, format_1.formatResponse)(recommendations, {
|
|
70
|
+
inputParameters: input,
|
|
71
|
+
});
|
|
72
|
+
this.logger('Pipeline completed successfully');
|
|
73
|
+
return response;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
this.logger(`Error in recommendation pipeline: ${error instanceof Error ? error.message : String(error)}`);
|
|
77
|
+
return this.handleError(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Creates a structured error response
|
|
82
|
+
* @param errorType - The type of error
|
|
83
|
+
* @param message - Human-readable error message
|
|
84
|
+
* @param details - Optional details for debugging
|
|
85
|
+
* @returns ErrorResponse object
|
|
86
|
+
*/
|
|
87
|
+
createErrorResponse(errorType, message, details) {
|
|
88
|
+
return {
|
|
89
|
+
error: true,
|
|
90
|
+
errorType,
|
|
91
|
+
message,
|
|
92
|
+
timestamp: new Date().toISOString(),
|
|
93
|
+
details,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Handles errors and converts them to structured error responses
|
|
98
|
+
* @param error - The error to handle
|
|
99
|
+
* @returns ErrorResponse object
|
|
100
|
+
*/
|
|
101
|
+
handleError(error) {
|
|
102
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
103
|
+
// Check for invalid API key errors
|
|
104
|
+
if (errorMessage.includes('401') ||
|
|
105
|
+
errorMessage.includes('Invalid API key') ||
|
|
106
|
+
errorMessage.includes('authentication')) {
|
|
107
|
+
return this.createErrorResponse('INVALID_API_KEY', 'Invalid or missing TMDB API key', errorMessage);
|
|
108
|
+
}
|
|
109
|
+
// Check for rate limit errors
|
|
110
|
+
if (errorMessage.includes('429') ||
|
|
111
|
+
errorMessage.includes('rate limit') ||
|
|
112
|
+
errorMessage.includes('Too Many Requests')) {
|
|
113
|
+
return this.createErrorResponse('RATE_LIMIT_EXCEEDED', 'TMDB API rate limit exceeded. Please try again later.', errorMessage);
|
|
114
|
+
}
|
|
115
|
+
// Check for MCP/network errors
|
|
116
|
+
if (errorMessage.includes('Network error') ||
|
|
117
|
+
errorMessage.includes('ECONNREFUSED') ||
|
|
118
|
+
errorMessage.includes('ENOTFOUND') ||
|
|
119
|
+
errorMessage.includes('timeout')) {
|
|
120
|
+
return this.createErrorResponse('MCP_UNAVAILABLE', 'Unable to connect to TMDB API service', errorMessage);
|
|
121
|
+
}
|
|
122
|
+
// Check for validation errors - be more comprehensive
|
|
123
|
+
if (errorMessage.includes('Invalid') ||
|
|
124
|
+
errorMessage.includes('must be') ||
|
|
125
|
+
errorMessage.includes('cannot be greater than') ||
|
|
126
|
+
errorMessage.includes('Year range invalid') ||
|
|
127
|
+
errorMessage.includes('runtime') ||
|
|
128
|
+
errorMessage.includes('year')) {
|
|
129
|
+
return this.createErrorResponse('VALIDATION_ERROR', errorMessage, errorMessage);
|
|
130
|
+
}
|
|
131
|
+
// Default to unknown error
|
|
132
|
+
return this.createErrorResponse('UNKNOWN_ERROR', 'An unexpected error occurred while processing your request', errorMessage);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Validates user input
|
|
136
|
+
* @param input - User input to validate
|
|
137
|
+
* @throws Error if validation fails
|
|
138
|
+
*/
|
|
139
|
+
validateInput(input) {
|
|
140
|
+
// Validate platforms if provided
|
|
141
|
+
if (input.platforms && input.platforms.length > 0) {
|
|
142
|
+
(0, validate_1.validatePlatforms)(input.platforms);
|
|
143
|
+
}
|
|
144
|
+
// Validate runtime constraints if provided
|
|
145
|
+
if (input.runtime) {
|
|
146
|
+
(0, validate_1.validateRuntime)(input.runtime);
|
|
147
|
+
}
|
|
148
|
+
// Validate release year if provided
|
|
149
|
+
if (input.releaseYear !== undefined) {
|
|
150
|
+
if (typeof input.releaseYear === 'number') {
|
|
151
|
+
(0, validate_1.validateYear)(input.releaseYear);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
(0, validate_1.validateYearRange)(input.releaseYear);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Resolves genres from mood or explicit genre input
|
|
160
|
+
* @param input - User input
|
|
161
|
+
* @returns Array of genre names
|
|
162
|
+
*/
|
|
163
|
+
resolveGenres(input) {
|
|
164
|
+
// Prioritize explicit genres
|
|
165
|
+
if (input.genre) {
|
|
166
|
+
return Array.isArray(input.genre) ? input.genre : [input.genre];
|
|
167
|
+
}
|
|
168
|
+
// Fall back to mood-based genres
|
|
169
|
+
if (input.mood) {
|
|
170
|
+
return (0, mood_1.moodToGenres)(input.mood);
|
|
171
|
+
}
|
|
172
|
+
// No genre preference
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Discovers candidate movies from TMDb
|
|
177
|
+
* @param input - User input
|
|
178
|
+
* @param genres - Resolved genres
|
|
179
|
+
* @returns Array of movie summaries
|
|
180
|
+
*/
|
|
181
|
+
async discoverCandidates(input, genres) {
|
|
182
|
+
// Build discover input
|
|
183
|
+
const discoverInput = {
|
|
184
|
+
genres: genres.length > 0 ? genres : undefined,
|
|
185
|
+
mood: input.mood,
|
|
186
|
+
};
|
|
187
|
+
// Add year constraints if provided
|
|
188
|
+
if (input.releaseYear !== undefined) {
|
|
189
|
+
if (typeof input.releaseYear === 'number') {
|
|
190
|
+
discoverInput.year = input.releaseYear;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
discoverInput.yearMin = input.releaseYear.from;
|
|
194
|
+
discoverInput.yearMax = input.releaseYear.to;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Add runtime constraints if provided
|
|
198
|
+
if (input.runtime) {
|
|
199
|
+
discoverInput.runtimeMin = input.runtime.min;
|
|
200
|
+
discoverInput.runtimeMax = input.runtime.max;
|
|
201
|
+
}
|
|
202
|
+
// Discover movies
|
|
203
|
+
const response = await (0, discover_1.discoverMovies)(discoverInput, this.tmdbClient);
|
|
204
|
+
// Fetch detailed information for top candidates
|
|
205
|
+
// Limit to top 20 to avoid excessive API calls
|
|
206
|
+
const topCandidates = response.results.slice(0, 20);
|
|
207
|
+
// Fetch details for each movie
|
|
208
|
+
const detailsPromises = topCandidates.map(movie => this.tmdbClient.getMovieDetails(movie.id));
|
|
209
|
+
const details = await Promise.all(detailsPromises);
|
|
210
|
+
return details;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Fetches watch providers for each candidate movie
|
|
214
|
+
* @param candidates - Array of movie details
|
|
215
|
+
* @returns Array of movies with platform information
|
|
216
|
+
*/
|
|
217
|
+
async fetchWatchProviders(candidates) {
|
|
218
|
+
const moviesWithProviders = [];
|
|
219
|
+
// Fetch providers for each movie
|
|
220
|
+
for (const movie of candidates) {
|
|
221
|
+
try {
|
|
222
|
+
const platforms = await (0, providers_1.getCanadianProviders)(movie.id, 'CA', this.tmdbClient);
|
|
223
|
+
// Only include movies with at least one provider
|
|
224
|
+
if (platforms.length > 0) {
|
|
225
|
+
moviesWithProviders.push({
|
|
226
|
+
...movie,
|
|
227
|
+
platforms,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
// Log error but continue with other movies
|
|
233
|
+
this.logger(`Failed to fetch providers for movie ${movie.id}: ${error instanceof Error ? error.message : String(error)}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return moviesWithProviders;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Applies user-specified filters to movies
|
|
240
|
+
* @param movies - Movies with provider information
|
|
241
|
+
* @param input - User input
|
|
242
|
+
* @returns Filtered movies
|
|
243
|
+
*/
|
|
244
|
+
applyFilters(movies, input) {
|
|
245
|
+
const filterOptions = {};
|
|
246
|
+
// Add platform filter if specified
|
|
247
|
+
if (input.platforms && input.platforms.length > 0) {
|
|
248
|
+
filterOptions.platforms = input.platforms;
|
|
249
|
+
}
|
|
250
|
+
// Add runtime filter if specified
|
|
251
|
+
if (input.runtime) {
|
|
252
|
+
filterOptions.runtime = input.runtime;
|
|
253
|
+
}
|
|
254
|
+
// Add year filter if specified
|
|
255
|
+
if (input.releaseYear !== undefined) {
|
|
256
|
+
if (typeof input.releaseYear === 'number') {
|
|
257
|
+
filterOptions.year = input.releaseYear;
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
filterOptions.year = {
|
|
261
|
+
from: input.releaseYear.from,
|
|
262
|
+
to: input.releaseYear.to,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return (0, filters_1.applyFilters)(movies, filterOptions);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Ranks movies and selects top 3-5
|
|
270
|
+
* @param movies - Filtered movies
|
|
271
|
+
* @param input - User input
|
|
272
|
+
* @returns Top 3-5 movies
|
|
273
|
+
*/
|
|
274
|
+
rankAndSelect(movies, input) {
|
|
275
|
+
// Build ranking input
|
|
276
|
+
const rankingInput = {
|
|
277
|
+
mood: input.mood,
|
|
278
|
+
genres: input.genre
|
|
279
|
+
? Array.isArray(input.genre)
|
|
280
|
+
? input.genre
|
|
281
|
+
: [input.genre]
|
|
282
|
+
: undefined,
|
|
283
|
+
platforms: input.platforms,
|
|
284
|
+
runtime: input.runtime,
|
|
285
|
+
};
|
|
286
|
+
// Add year preferences for ranking
|
|
287
|
+
if (input.releaseYear !== undefined) {
|
|
288
|
+
if (typeof input.releaseYear === 'number') {
|
|
289
|
+
rankingInput.year = { preferred: input.releaseYear };
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
rankingInput.year = {
|
|
293
|
+
from: input.releaseYear.from,
|
|
294
|
+
to: input.releaseYear.to,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Rank movies
|
|
299
|
+
const ranked = (0, ranking_1.rankMovies)(movies, rankingInput);
|
|
300
|
+
// Select top 3-5 movies
|
|
301
|
+
const count = Math.min(5, Math.max(3, ranked.length));
|
|
302
|
+
return ranked.slice(0, count);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Formats movies into recommendations
|
|
306
|
+
* @param movies - Selected movies
|
|
307
|
+
* @param input - User input
|
|
308
|
+
* @returns Array of formatted recommendations
|
|
309
|
+
*/
|
|
310
|
+
formatRecommendations(movies, input) {
|
|
311
|
+
return movies.map(movie => {
|
|
312
|
+
// Build streaming platform information
|
|
313
|
+
const streamingPlatforms = movie.platforms.map(name => ({
|
|
314
|
+
name,
|
|
315
|
+
type: 'subscription',
|
|
316
|
+
available: true,
|
|
317
|
+
}));
|
|
318
|
+
// Generate match reason based on input
|
|
319
|
+
const reason = this.generateMatchReason(movie, input);
|
|
320
|
+
// Format as recommendation
|
|
321
|
+
return (0, format_1.toRecommendation)({
|
|
322
|
+
id: movie.id,
|
|
323
|
+
title: movie.title,
|
|
324
|
+
release_date: movie.release_date || '',
|
|
325
|
+
runtime: movie.runtime || 0,
|
|
326
|
+
overview: movie.overview || '',
|
|
327
|
+
genres: movie.genres || [],
|
|
328
|
+
}, streamingPlatforms, reason);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Generates a match reason for a movie
|
|
333
|
+
* @param movie - Movie to explain
|
|
334
|
+
* @param input - User input
|
|
335
|
+
* @returns Match reason string
|
|
336
|
+
*/
|
|
337
|
+
generateMatchReason(movie, input) {
|
|
338
|
+
const reasons = [];
|
|
339
|
+
// Genre match
|
|
340
|
+
const movieGenres = movie.genres?.map(g => g.name) || [];
|
|
341
|
+
const userGenres = this.resolveGenres(input);
|
|
342
|
+
const matchedGenres = movieGenres.filter(g => userGenres.includes(g));
|
|
343
|
+
if (matchedGenres.length > 0) {
|
|
344
|
+
reasons.push(`matches your ${input.mood ? `${input.mood} mood` : 'genre preferences'} (${matchedGenres.join(', ')})`);
|
|
345
|
+
}
|
|
346
|
+
// Platform availability
|
|
347
|
+
if (input.platforms && input.platforms.length > 0) {
|
|
348
|
+
const matchedPlatforms = movie.platforms.filter(p => input.platforms.includes(p));
|
|
349
|
+
if (matchedPlatforms.length > 0) {
|
|
350
|
+
reasons.push(`available on ${matchedPlatforms.join(', ')}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Popularity
|
|
354
|
+
if (movie.popularity && movie.popularity > 50) {
|
|
355
|
+
reasons.push('highly rated');
|
|
356
|
+
}
|
|
357
|
+
// Default reason if none match
|
|
358
|
+
if (reasons.length === 0) {
|
|
359
|
+
reasons.push('recommended based on your preferences');
|
|
360
|
+
}
|
|
361
|
+
return reasons.join(', ');
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
exports.MovieAgent = MovieAgent;
|
|
365
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple in-memory cache with TTL support
|
|
3
|
+
*/
|
|
4
|
+
export declare class Cache {
|
|
5
|
+
private store;
|
|
6
|
+
private defaultTtl;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new cache instance
|
|
9
|
+
* @param defaultTtl Default time-to-live in seconds
|
|
10
|
+
*/
|
|
11
|
+
constructor(defaultTtl?: number);
|
|
12
|
+
/**
|
|
13
|
+
* Sets a value in the cache
|
|
14
|
+
* @param key Cache key
|
|
15
|
+
* @param value Value to cache
|
|
16
|
+
* @param ttl Time-to-live in seconds (optional, uses default if not provided)
|
|
17
|
+
*/
|
|
18
|
+
set<T>(key: string, value: T, ttl?: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* Gets a value from the cache
|
|
21
|
+
* @param key Cache key
|
|
22
|
+
* @returns Cached value or undefined if not found or expired
|
|
23
|
+
*/
|
|
24
|
+
get<T>(key: string): T | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Checks if a key exists and is not expired
|
|
27
|
+
* @param key Cache key
|
|
28
|
+
* @returns true if key exists and is not expired
|
|
29
|
+
*/
|
|
30
|
+
has(key: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Deletes a key from the cache
|
|
33
|
+
* @param key Cache key
|
|
34
|
+
* @returns true if key existed and was deleted
|
|
35
|
+
*/
|
|
36
|
+
delete(key: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Clears all entries from the cache
|
|
39
|
+
*/
|
|
40
|
+
clear(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Gets the number of entries in the cache (including expired ones)
|
|
43
|
+
* @returns Number of entries
|
|
44
|
+
*/
|
|
45
|
+
size(): number;
|
|
46
|
+
/**
|
|
47
|
+
* Removes all expired entries from the cache
|
|
48
|
+
* @returns Number of entries removed
|
|
49
|
+
*/
|
|
50
|
+
prune(): number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Gets the global cache instance
|
|
54
|
+
* @param ttl Default TTL for the cache (only used on first call)
|
|
55
|
+
* @returns Global cache instance
|
|
56
|
+
*/
|
|
57
|
+
export declare function getCache(ttl?: number): Cache;
|
|
58
|
+
/**
|
|
59
|
+
* Resets the global cache instance (useful for testing)
|
|
60
|
+
*/
|
|
61
|
+
export declare function resetCache(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Generates a cache key for discover parameters
|
|
64
|
+
* @param params Discover parameters object
|
|
65
|
+
* @returns Cache key string
|
|
66
|
+
*/
|
|
67
|
+
export declare function generateDiscoverCacheKey(params: Record<string, any>): string;
|
|
68
|
+
/**
|
|
69
|
+
* Generates a cache key for watch providers
|
|
70
|
+
* @param movieId Movie ID
|
|
71
|
+
* @param region Region code
|
|
72
|
+
* @returns Cache key string
|
|
73
|
+
*/
|
|
74
|
+
export declare function generateProvidersCacheKey(movieId: number | string, region: string): string;
|
|
75
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,UAAU,CAAS;IAE3B;;;OAGG;gBACS,UAAU,GAAE,MAAa;IAKrC;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAMjD;;;;OAIG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAgBlC;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;OAGG;IACH,IAAI,IAAI,MAAM;IAId;;;OAGG;IACH,KAAK,IAAI,MAAM;CAahB;AAKD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAK5C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAK5E;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,MAAM,EAAE,MAAM,GACb,MAAM,CAER"}
|