@telepat/snoopy 0.1.4

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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +255 -0
  3. package/dist/src/cli/commands/analytics.d.ts +3 -0
  4. package/dist/src/cli/commands/analytics.js +147 -0
  5. package/dist/src/cli/commands/analytics.js.map +1 -0
  6. package/dist/src/cli/commands/daemon.d.ts +5 -0
  7. package/dist/src/cli/commands/daemon.js +85 -0
  8. package/dist/src/cli/commands/daemon.js.map +1 -0
  9. package/dist/src/cli/commands/doctor.d.ts +1 -0
  10. package/dist/src/cli/commands/doctor.js +106 -0
  11. package/dist/src/cli/commands/doctor.js.map +1 -0
  12. package/dist/src/cli/commands/errors.d.ts +3 -0
  13. package/dist/src/cli/commands/errors.js +51 -0
  14. package/dist/src/cli/commands/errors.js.map +1 -0
  15. package/dist/src/cli/commands/export.d.ts +1 -0
  16. package/dist/src/cli/commands/export.js +48 -0
  17. package/dist/src/cli/commands/export.js.map +1 -0
  18. package/dist/src/cli/commands/job.d.ts +16 -0
  19. package/dist/src/cli/commands/job.js +350 -0
  20. package/dist/src/cli/commands/job.js.map +1 -0
  21. package/dist/src/cli/commands/logs.d.ts +3 -0
  22. package/dist/src/cli/commands/logs.js +44 -0
  23. package/dist/src/cli/commands/logs.js.map +1 -0
  24. package/dist/src/cli/commands/selection.d.ts +19 -0
  25. package/dist/src/cli/commands/selection.js +182 -0
  26. package/dist/src/cli/commands/selection.js.map +1 -0
  27. package/dist/src/cli/commands/settings.d.ts +1 -0
  28. package/dist/src/cli/commands/settings.js +31 -0
  29. package/dist/src/cli/commands/settings.js.map +1 -0
  30. package/dist/src/cli/commands/startup.d.ts +5 -0
  31. package/dist/src/cli/commands/startup.js +26 -0
  32. package/dist/src/cli/commands/startup.js.map +1 -0
  33. package/dist/src/cli/flows/jobAddFlow.d.ts +26 -0
  34. package/dist/src/cli/flows/jobAddFlow.js +209 -0
  35. package/dist/src/cli/flows/jobAddFlow.js.map +1 -0
  36. package/dist/src/cli/flows/settingsFlow.d.ts +15 -0
  37. package/dist/src/cli/flows/settingsFlow.js +180 -0
  38. package/dist/src/cli/flows/settingsFlow.js.map +1 -0
  39. package/dist/src/cli/flows/settingsFlowModel.d.ts +47 -0
  40. package/dist/src/cli/flows/settingsFlowModel.js +143 -0
  41. package/dist/src/cli/flows/settingsFlowModel.js.map +1 -0
  42. package/dist/src/cli/index.d.ts +2 -0
  43. package/dist/src/cli/index.js +138 -0
  44. package/dist/src/cli/index.js.map +1 -0
  45. package/dist/src/cli/ui/consoleUi.d.ts +13 -0
  46. package/dist/src/cli/ui/consoleUi.js +165 -0
  47. package/dist/src/cli/ui/consoleUi.js.map +1 -0
  48. package/dist/src/cli/ui/time.d.ts +9 -0
  49. package/dist/src/cli/ui/time.js +35 -0
  50. package/dist/src/cli/ui/time.js.map +1 -0
  51. package/dist/src/index.d.ts +1 -0
  52. package/dist/src/index.js +2 -0
  53. package/dist/src/index.js.map +1 -0
  54. package/dist/src/scripts/e2eSmoke.d.ts +1 -0
  55. package/dist/src/scripts/e2eSmoke.js +102 -0
  56. package/dist/src/scripts/e2eSmoke.js.map +1 -0
  57. package/dist/src/services/analytics/analyticsService.d.ts +50 -0
  58. package/dist/src/services/analytics/analyticsService.js +88 -0
  59. package/dist/src/services/analytics/analyticsService.js.map +1 -0
  60. package/dist/src/services/daemonControl.d.ts +12 -0
  61. package/dist/src/services/daemonControl.js +58 -0
  62. package/dist/src/services/daemonControl.js.map +1 -0
  63. package/dist/src/services/db/repositories/jobsRepo.d.ts +19 -0
  64. package/dist/src/services/db/repositories/jobsRepo.js +164 -0
  65. package/dist/src/services/db/repositories/jobsRepo.js.map +1 -0
  66. package/dist/src/services/db/repositories/runsRepo.d.ts +58 -0
  67. package/dist/src/services/db/repositories/runsRepo.js +190 -0
  68. package/dist/src/services/db/repositories/runsRepo.js.map +1 -0
  69. package/dist/src/services/db/repositories/scanItemsRepo.d.ts +69 -0
  70. package/dist/src/services/db/repositories/scanItemsRepo.js +176 -0
  71. package/dist/src/services/db/repositories/scanItemsRepo.js.map +1 -0
  72. package/dist/src/services/db/repositories/settingsRepo.d.ts +14 -0
  73. package/dist/src/services/db/repositories/settingsRepo.js +132 -0
  74. package/dist/src/services/db/repositories/settingsRepo.js.map +1 -0
  75. package/dist/src/services/db/sqlite.d.ts +2 -0
  76. package/dist/src/services/db/sqlite.js +192 -0
  77. package/dist/src/services/db/sqlite.js.map +1 -0
  78. package/dist/src/services/export/csvResults.d.ts +10 -0
  79. package/dist/src/services/export/csvResults.js +42 -0
  80. package/dist/src/services/export/csvResults.js.map +1 -0
  81. package/dist/src/services/logging/logReader.d.ts +4 -0
  82. package/dist/src/services/logging/logReader.js +230 -0
  83. package/dist/src/services/logging/logReader.js.map +1 -0
  84. package/dist/src/services/logging/logRotation.d.ts +1 -0
  85. package/dist/src/services/logging/logRotation.js +30 -0
  86. package/dist/src/services/logging/logRotation.js.map +1 -0
  87. package/dist/src/services/logging/runLogger.d.ts +9 -0
  88. package/dist/src/services/logging/runLogger.js +42 -0
  89. package/dist/src/services/logging/runLogger.js.map +1 -0
  90. package/dist/src/services/openrouter/client.d.ts +60 -0
  91. package/dist/src/services/openrouter/client.js +437 -0
  92. package/dist/src/services/openrouter/client.js.map +1 -0
  93. package/dist/src/services/openrouter/prompts.d.ts +5 -0
  94. package/dist/src/services/openrouter/prompts.js +48 -0
  95. package/dist/src/services/openrouter/prompts.js.map +1 -0
  96. package/dist/src/services/reddit/client.d.ts +25 -0
  97. package/dist/src/services/reddit/client.js +186 -0
  98. package/dist/src/services/reddit/client.js.map +1 -0
  99. package/dist/src/services/scheduler/cronScheduler.d.ts +11 -0
  100. package/dist/src/services/scheduler/cronScheduler.js +76 -0
  101. package/dist/src/services/scheduler/cronScheduler.js.map +1 -0
  102. package/dist/src/services/scheduler/jobRunner.d.ts +76 -0
  103. package/dist/src/services/scheduler/jobRunner.js +414 -0
  104. package/dist/src/services/scheduler/jobRunner.js.map +1 -0
  105. package/dist/src/services/scheduler/jobRunnerStub.d.ts +5 -0
  106. package/dist/src/services/scheduler/jobRunnerStub.js +11 -0
  107. package/dist/src/services/scheduler/jobRunnerStub.js.map +1 -0
  108. package/dist/src/services/security/secretStore.d.ts +6 -0
  109. package/dist/src/services/security/secretStore.js +193 -0
  110. package/dist/src/services/security/secretStore.js.map +1 -0
  111. package/dist/src/services/startup/index.d.ts +13 -0
  112. package/dist/src/services/startup/index.js +120 -0
  113. package/dist/src/services/startup/index.js.map +1 -0
  114. package/dist/src/services/startup/linuxCronFallback.d.ts +2 -0
  115. package/dist/src/services/startup/linuxCronFallback.js +29 -0
  116. package/dist/src/services/startup/linuxCronFallback.js.map +1 -0
  117. package/dist/src/services/startup/linuxSystemd.d.ts +3 -0
  118. package/dist/src/services/startup/linuxSystemd.js +47 -0
  119. package/dist/src/services/startup/linuxSystemd.js.map +1 -0
  120. package/dist/src/services/startup/macosLaunchd.d.ts +2 -0
  121. package/dist/src/services/startup/macosLaunchd.js +40 -0
  122. package/dist/src/services/startup/macosLaunchd.js.map +1 -0
  123. package/dist/src/services/startup/windowsRunFallback.d.ts +2 -0
  124. package/dist/src/services/startup/windowsRunFallback.js +17 -0
  125. package/dist/src/services/startup/windowsRunFallback.js.map +1 -0
  126. package/dist/src/services/startup/windowsTaskScheduler.d.ts +2 -0
  127. package/dist/src/services/startup/windowsTaskScheduler.js +16 -0
  128. package/dist/src/services/startup/windowsTaskScheduler.js.map +1 -0
  129. package/dist/src/types/job.d.ts +34 -0
  130. package/dist/src/types/job.js +2 -0
  131. package/dist/src/types/job.js.map +1 -0
  132. package/dist/src/types/settings.d.ts +35 -0
  133. package/dist/src/types/settings.js +8 -0
  134. package/dist/src/types/settings.js.map +1 -0
  135. package/dist/src/ui/components/AppFrame.d.ts +17 -0
  136. package/dist/src/ui/components/AppFrame.js +26 -0
  137. package/dist/src/ui/components/AppFrame.js.map +1 -0
  138. package/dist/src/ui/components/CliHeader.d.ts +8 -0
  139. package/dist/src/ui/components/CliHeader.js +8 -0
  140. package/dist/src/ui/components/CliHeader.js.map +1 -0
  141. package/dist/src/ui/components/SubredditMultiSelect.d.ts +7 -0
  142. package/dist/src/ui/components/SubredditMultiSelect.js +91 -0
  143. package/dist/src/ui/components/SubredditMultiSelect.js.map +1 -0
  144. package/dist/src/ui/components/TextPrompt.d.ts +10 -0
  145. package/dist/src/ui/components/TextPrompt.js +13 -0
  146. package/dist/src/ui/components/TextPrompt.js.map +1 -0
  147. package/dist/src/ui/components/YesNoSelector.d.ts +10 -0
  148. package/dist/src/ui/components/YesNoSelector.js +25 -0
  149. package/dist/src/ui/components/YesNoSelector.js.map +1 -0
  150. package/dist/src/ui/components/subredditOptions.d.ts +5 -0
  151. package/dist/src/ui/components/subredditOptions.js +14 -0
  152. package/dist/src/ui/components/subredditOptions.js.map +1 -0
  153. package/dist/src/ui/components/yesNoSelectorModel.d.ts +9 -0
  154. package/dist/src/ui/components/yesNoSelectorModel.js +23 -0
  155. package/dist/src/ui/components/yesNoSelectorModel.js.map +1 -0
  156. package/dist/src/ui/theme.d.ts +26 -0
  157. package/dist/src/ui/theme.js +37 -0
  158. package/dist/src/ui/theme.js.map +1 -0
  159. package/dist/src/utils/logger.d.ts +5 -0
  160. package/dist/src/utils/logger.js +15 -0
  161. package/dist/src/utils/logger.js.map +1 -0
  162. package/dist/src/utils/notify.d.ts +6 -0
  163. package/dist/src/utils/notify.js +14 -0
  164. package/dist/src/utils/notify.js.map +1 -0
  165. package/dist/src/utils/paths.d.ts +10 -0
  166. package/dist/src/utils/paths.js +24 -0
  167. package/dist/src/utils/paths.js.map +1 -0
  168. package/dist/src/utils/scanLogFormatting.d.ts +26 -0
  169. package/dist/src/utils/scanLogFormatting.js +60 -0
  170. package/dist/src/utils/scanLogFormatting.js.map +1 -0
  171. package/package.json +74 -0
@@ -0,0 +1 @@
1
+ export declare function cleanupOldLogs(maxAgeMs?: number): void;
@@ -0,0 +1,30 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { ensureAppDirs } from '../../utils/paths.js';
4
+ const DEFAULT_MAX_AGE_MS = 5 * 24 * 60 * 60 * 1000; // 5 days
5
+ export function cleanupOldLogs(maxAgeMs = DEFAULT_MAX_AGE_MS) {
6
+ const paths = ensureAppDirs();
7
+ const logsDir = path.join(paths.rootDir, 'logs');
8
+ if (!fs.existsSync(logsDir)) {
9
+ return;
10
+ }
11
+ const now = Date.now();
12
+ const files = fs.readdirSync(logsDir);
13
+ for (const file of files) {
14
+ if (!file.startsWith('run-') || !file.endsWith('.log')) {
15
+ continue;
16
+ }
17
+ const filePath = path.join(logsDir, file);
18
+ try {
19
+ const stat = fs.statSync(filePath);
20
+ const age = now - stat.mtime.getTime();
21
+ if (age > maxAgeMs) {
22
+ fs.unlinkSync(filePath);
23
+ }
24
+ }
25
+ catch {
26
+ // Ignore errors (file might have been deleted, permission issues, etc.)
27
+ }
28
+ }
29
+ }
30
+ //# sourceMappingURL=logRotation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logRotation.js","sourceRoot":"","sources":["../../../../src/services/logging/logRotation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;AAE7D,MAAM,UAAU,cAAc,CAAC,WAAmB,kBAAkB;IAClE,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEjD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACvD,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAEvC,IAAI,GAAG,GAAG,QAAQ,EAAE,CAAC;gBACnB,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wEAAwE;QAC1E,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface RunLogger {
2
+ info(message: string): void;
3
+ warn(message: string): void;
4
+ error(message: string): void;
5
+ logRequest(method: string, endpoint: string, payload: unknown): void;
6
+ logResponse(statusCode: number | string, body: unknown): void;
7
+ getLogFilePath(): string;
8
+ }
9
+ export declare function createRunLogger(runId: string): RunLogger;
@@ -0,0 +1,42 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { ensureAppDirs } from '../../utils/paths.js';
4
+ export function createRunLogger(runId) {
5
+ const paths = ensureAppDirs();
6
+ const logsDir = path.join(paths.rootDir, 'logs');
7
+ const logFilePath = path.join(logsDir, `run-${runId}.log`);
8
+ // Ensure logs directory exists
9
+ if (!fs.existsSync(logsDir)) {
10
+ fs.mkdirSync(logsDir, { recursive: true });
11
+ }
12
+ function formatTimestamp() {
13
+ return new Date().toISOString();
14
+ }
15
+ function writeLog(level, message) {
16
+ const entry = `[${formatTimestamp()}] [${level}] ${message}\n`;
17
+ fs.appendFileSync(logFilePath, entry, 'utf8');
18
+ }
19
+ return {
20
+ info(message) {
21
+ writeLog('INFO', message);
22
+ },
23
+ warn(message) {
24
+ writeLog('WARN', message);
25
+ },
26
+ error(message) {
27
+ writeLog('ERROR', message);
28
+ },
29
+ logRequest(method, endpoint, payload) {
30
+ const entry = `[${formatTimestamp()}] [REQUEST] ${method} ${endpoint}\n${JSON.stringify(payload, null, 2)}\n`;
31
+ fs.appendFileSync(logFilePath, entry, 'utf8');
32
+ },
33
+ logResponse(statusCode, body) {
34
+ const entry = `[${formatTimestamp()}] [RESPONSE] Status ${statusCode}\n${JSON.stringify(body, null, 2)}\n`;
35
+ fs.appendFileSync(logFilePath, entry, 'utf8');
36
+ },
37
+ getLogFilePath() {
38
+ return logFilePath;
39
+ }
40
+ };
41
+ }
42
+ //# sourceMappingURL=runLogger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runLogger.js","sourceRoot":"","sources":["../../../../src/services/logging/runLogger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAWrD,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,CAAC;IAE3D,+BAA+B;IAC/B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,SAAS,eAAe;QACtB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;IAED,SAAS,QAAQ,CAAC,KAAa,EAAE,OAAe;QAC9C,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,MAAM,KAAK,KAAK,OAAO,IAAI,CAAC;QAC/D,EAAE,CAAC,cAAc,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAED,OAAO;QACL,IAAI,CAAC,OAAe;YAClB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,OAAe;YAClB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,KAAK,CAAC,OAAe;YACnB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7B,CAAC;QAED,UAAU,CAAC,MAAc,EAAE,QAAgB,EAAE,OAAgB;YAC3D,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,eAAe,MAAM,IAAI,QAAQ,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;YAC9G,EAAE,CAAC,cAAc,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;QAED,WAAW,CAAC,UAA2B,EAAE,IAAa;YACpD,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,uBAAuB,UAAU,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;YAC3G,EAAE,CAAC,cAAc,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;QAED,cAAc;YACZ,OAAO,WAAW,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,60 @@
1
+ import type { ClarificationQuestion, GeneratedJobSpec } from '../../types/job.js';
2
+ import type { ModelSettings } from '../../types/settings.js';
3
+ import type { RedditComment } from '../reddit/client.js';
4
+ export interface QualificationResult {
5
+ qualified: boolean;
6
+ reason: string;
7
+ promptTokens: number;
8
+ completionTokens: number;
9
+ }
10
+ export interface OpenRouterTraceHooks {
11
+ onRequest?: (operation: string, payload: unknown) => void;
12
+ onResponse?: (operation: string, payload: unknown) => void;
13
+ onError?: (operation: string, payload: unknown) => void;
14
+ }
15
+ interface QualificationRequestBase {
16
+ model: string;
17
+ modelSettings: ModelSettings;
18
+ qualificationPrompt: string;
19
+ }
20
+ interface QualifyPostRequest extends QualificationRequestBase {
21
+ postTitle: string;
22
+ postBody: string;
23
+ }
24
+ interface QualifyCommentThreadRequest extends QualificationRequestBase {
25
+ postTitle: string;
26
+ targetAuthor: string;
27
+ thread: RedditComment[];
28
+ }
29
+ export interface OpenRouterModelOption {
30
+ id: string;
31
+ name: string;
32
+ }
33
+ export declare class OpenRouterClientError extends Error {
34
+ readonly kind: 'auth' | 'rate_limit' | 'api' | 'parse' | 'unknown';
35
+ constructor(kind: OpenRouterClientError['kind'], message: string);
36
+ }
37
+ export declare class OpenRouterClient {
38
+ private readonly client;
39
+ private readonly apiKey;
40
+ private readonly modelCapabilityCache;
41
+ private readonly traceHooks?;
42
+ constructor(apiKey: string, traceHooks?: OpenRouterTraceHooks);
43
+ private traceRequest;
44
+ private traceResponse;
45
+ private traceError;
46
+ modelSupportsTools(model: string): Promise<boolean>;
47
+ listModels(): Promise<OpenRouterModelOption[]>;
48
+ generateClarificationQuestions(criteria: string, model: string): Promise<ClarificationQuestion[]>;
49
+ generateJobSpec(criteria: string, answers: Array<{
50
+ question: string;
51
+ answer: string;
52
+ }>, model: string): Promise<GeneratedJobSpec>;
53
+ qualifyPost(input: QualifyPostRequest): Promise<QualificationResult>;
54
+ qualifyCommentThread(input: QualifyCommentThreadRequest): Promise<QualificationResult>;
55
+ private runQualification;
56
+ private isTruncatedWithoutStructuredOutput;
57
+ private parseQualificationToolCalls;
58
+ private parseQualificationContent;
59
+ }
60
+ export {};
@@ -0,0 +1,437 @@
1
+ import OpenAI from 'openai';
2
+ import { z } from 'zod';
3
+ import { logger } from '../../utils/logger.js';
4
+ import { buildClarificationPrompt, buildSpecPrompt } from './prompts.js';
5
+ const clarificationSchema = z.object({
6
+ questions: z.array(z.object({ id: z.string(), question: z.string() })).min(1)
7
+ });
8
+ const specSchema = z.object({
9
+ name: z.string().min(3),
10
+ slug: z.string().min(2),
11
+ description: z.string().min(5),
12
+ qualificationPrompt: z.string().min(8),
13
+ suggestedSubreddits: z.array(z.string().min(2)).min(1)
14
+ });
15
+ const qualifySchema = z.object({
16
+ qualified: z.boolean(),
17
+ reason: z.string().min(1).max(80)
18
+ });
19
+ const QUALIFICATION_TOOL_NAME = 'submit_qualification';
20
+ const QUALIFICATION_TOOL = {
21
+ type: 'function',
22
+ function: {
23
+ name: QUALIFICATION_TOOL_NAME,
24
+ description: 'Submit final qualification result for one Reddit item. Use concise reason text only.',
25
+ parameters: {
26
+ type: 'object',
27
+ properties: {
28
+ qualified: {
29
+ type: 'boolean'
30
+ },
31
+ reason: {
32
+ type: 'string',
33
+ maxLength: 80,
34
+ description: 'A short reason under 80 characters.'
35
+ }
36
+ },
37
+ required: ['qualified', 'reason'],
38
+ additionalProperties: false
39
+ }
40
+ }
41
+ };
42
+ export class OpenRouterClientError extends Error {
43
+ kind;
44
+ constructor(kind, message) {
45
+ super(message);
46
+ this.name = 'OpenRouterClientError';
47
+ this.kind = kind;
48
+ }
49
+ }
50
+ function extractJsonPayload(raw) {
51
+ const trimmed = raw.trim();
52
+ const fencedMatch = trimmed.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);
53
+ if (fencedMatch?.[1]) {
54
+ return fencedMatch[1].trim();
55
+ }
56
+ const firstBrace = trimmed.indexOf('{');
57
+ const lastBrace = trimmed.lastIndexOf('}');
58
+ if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
59
+ return trimmed.slice(firstBrace, lastBrace + 1);
60
+ }
61
+ const firstBracket = trimmed.indexOf('[');
62
+ const lastBracket = trimmed.lastIndexOf(']');
63
+ if (firstBracket !== -1 && lastBracket !== -1 && lastBracket > firstBracket) {
64
+ return trimmed.slice(firstBracket, lastBracket + 1);
65
+ }
66
+ return trimmed;
67
+ }
68
+ function parseStructuredJson(raw) {
69
+ try {
70
+ return JSON.parse(extractJsonPayload(raw));
71
+ }
72
+ catch (error) {
73
+ throw new OpenRouterClientError('parse', `OpenRouter returned a response that was not valid JSON. ${error instanceof Error ? error.message : String(error)}`);
74
+ }
75
+ }
76
+ function toOpenRouterError(error) {
77
+ if (error instanceof OpenRouterClientError) {
78
+ return error;
79
+ }
80
+ if (error instanceof OpenAI.AuthenticationError) {
81
+ return new OpenRouterClientError('auth', 'OpenRouter authentication failed. Check your API key and try again.');
82
+ }
83
+ if (error instanceof OpenAI.RateLimitError) {
84
+ return new OpenRouterClientError('rate_limit', 'OpenRouter rate limit reached. Try again shortly.');
85
+ }
86
+ if (error instanceof OpenAI.APIError) {
87
+ return new OpenRouterClientError('api', `OpenRouter request failed (${error.status ?? 'unknown status'}). ${error.message}`);
88
+ }
89
+ if (error instanceof Error) {
90
+ return new OpenRouterClientError('unknown', error.message);
91
+ }
92
+ return new OpenRouterClientError('unknown', 'OpenRouter request failed for an unknown reason.');
93
+ }
94
+ function tryExtractQualification(raw) {
95
+ const trimmed = raw.trim();
96
+ const qualifiedMatch = trimmed.match(/"qualified"\s*:\s*(true|false)/i);
97
+ const reasonMatch = trimmed.match(/"reason"\s*:\s*"([\s\S]*)/i);
98
+ if (!qualifiedMatch || !reasonMatch) {
99
+ return null;
100
+ }
101
+ let reason = reasonMatch[1]
102
+ .replace(/\\n/g, ' ')
103
+ .replace(/\\"/g, '"')
104
+ .replace(/["}\]]+\s*$/, '')
105
+ .trim();
106
+ if (!reason) {
107
+ reason = 'No reason provided';
108
+ }
109
+ return {
110
+ qualified: qualifiedMatch[1].toLowerCase() === 'true',
111
+ reason: reason.slice(0, 80)
112
+ };
113
+ }
114
+ export class OpenRouterClient {
115
+ client;
116
+ apiKey;
117
+ modelCapabilityCache = new Map();
118
+ traceHooks;
119
+ constructor(apiKey, traceHooks) {
120
+ this.apiKey = apiKey;
121
+ this.traceHooks = traceHooks;
122
+ this.client = new OpenAI({
123
+ apiKey,
124
+ baseURL: 'https://openrouter.ai/api/v1'
125
+ });
126
+ }
127
+ traceRequest(operation, payload) {
128
+ this.traceHooks?.onRequest?.(operation, payload);
129
+ }
130
+ traceResponse(operation, payload) {
131
+ this.traceHooks?.onResponse?.(operation, payload);
132
+ }
133
+ traceError(operation, error) {
134
+ this.traceHooks?.onError?.(operation, {
135
+ message: error instanceof Error ? error.message : String(error),
136
+ stack: error instanceof Error ? error.stack : undefined
137
+ });
138
+ }
139
+ async modelSupportsTools(model) {
140
+ if (this.modelCapabilityCache.has(model)) {
141
+ return this.modelCapabilityCache.get(model);
142
+ }
143
+ try {
144
+ const response = await fetch('https://openrouter.ai/api/v1/models', {
145
+ headers: { Authorization: `Bearer ${this.apiKey}` }
146
+ });
147
+ if (!response.ok) {
148
+ this.modelCapabilityCache.set(model, false);
149
+ return false;
150
+ }
151
+ const json = (await response.json());
152
+ const modelData = (json.data ?? []).find((m) => m.id === model);
153
+ const supports = modelData?.supported_parameters?.includes('tools') ?? false;
154
+ this.modelCapabilityCache.set(model, supports);
155
+ return supports;
156
+ }
157
+ catch {
158
+ this.modelCapabilityCache.set(model, false);
159
+ return false;
160
+ }
161
+ }
162
+ async listModels() {
163
+ const response = await fetch('https://openrouter.ai/api/v1/models', {
164
+ headers: {
165
+ Authorization: `Bearer ${this.apiKey}`
166
+ }
167
+ });
168
+ if (!response.ok) {
169
+ throw new Error(`Failed to fetch models (${response.status})`);
170
+ }
171
+ const json = (await response.json());
172
+ return (json.data ?? []).slice(0, 50).map((item) => ({
173
+ id: item.id,
174
+ name: item.name ?? item.id
175
+ }));
176
+ }
177
+ async generateClarificationQuestions(criteria, model) {
178
+ try {
179
+ const completion = await this.client.chat.completions.create({
180
+ model,
181
+ temperature: 0.2,
182
+ messages: [{ role: 'user', content: buildClarificationPrompt(criteria) }]
183
+ });
184
+ const raw = completion.choices[0]?.message?.content ?? '';
185
+ const parsed = clarificationSchema.parse(parseStructuredJson(raw));
186
+ return parsed.questions.slice(0, 4);
187
+ }
188
+ catch (error) {
189
+ throw toOpenRouterError(error);
190
+ }
191
+ }
192
+ async generateJobSpec(criteria, answers, model) {
193
+ try {
194
+ const completion = await this.client.chat.completions.create({
195
+ model,
196
+ temperature: 0.4,
197
+ messages: [{ role: 'user', content: buildSpecPrompt(criteria, answers) }]
198
+ });
199
+ const raw = completion.choices[0]?.message?.content ?? '';
200
+ const parsed = specSchema.parse(parseStructuredJson(raw));
201
+ return {
202
+ name: parsed.name,
203
+ slug: parsed.slug,
204
+ description: parsed.description,
205
+ qualificationPrompt: parsed.qualificationPrompt,
206
+ suggestedSubreddits: parsed.suggestedSubreddits.map((value) => value.replace(/^r\//i, '').trim())
207
+ };
208
+ }
209
+ catch (error) {
210
+ throw toOpenRouterError(error);
211
+ }
212
+ }
213
+ async qualifyPost(input) {
214
+ const userMessage = [`Post title: ${input.postTitle}`, '', `Post body: ${input.postBody}`].join('\n');
215
+ return this.runQualification(input, userMessage);
216
+ }
217
+ async qualifyCommentThread(input) {
218
+ const threadText = input.thread
219
+ .map((comment) => `${comment.author}: ${comment.body}`)
220
+ .join('\n');
221
+ const userMessage = [
222
+ `Post title: ${input.postTitle}`,
223
+ '',
224
+ 'Comment thread (chronological):',
225
+ threadText,
226
+ '',
227
+ `Important: decide qualification based on the most recent comment by ${input.targetAuthor}.`,
228
+ 'Use other thread context only for interpretation.'
229
+ ].join('\n');
230
+ return this.runQualification(input, userMessage);
231
+ }
232
+ async runQualification(input, userMessage) {
233
+ const systemPrompt = [
234
+ 'You are a lead qualification classifier for Reddit monitoring jobs.',
235
+ '',
236
+ 'Apply this qualification rubric exactly:',
237
+ input.qualificationPrompt,
238
+ '',
239
+ 'Respond only as JSON with this schema:',
240
+ '{"qualified": boolean, "reason": string}',
241
+ 'The reason must be concise, no more than 12 words, and no more than 80 characters.'
242
+ ].join('\n');
243
+ const supportsTools = await this.modelSupportsTools(input.model);
244
+ const baseMaxTokens = Math.max(80, input.modelSettings.maxTokens);
245
+ const expandedMaxTokens = Math.max(baseMaxTokens, 800);
246
+ try {
247
+ let parsed = null;
248
+ let promptTokens = 0;
249
+ let completionTokens = 0;
250
+ if (supportsTools) {
251
+ const toolPayload = {
252
+ model: input.model,
253
+ temperature: input.modelSettings.temperature,
254
+ top_p: input.modelSettings.topP,
255
+ max_tokens: baseMaxTokens,
256
+ tools: [QUALIFICATION_TOOL],
257
+ tool_choice: {
258
+ type: 'function',
259
+ function: {
260
+ name: QUALIFICATION_TOOL_NAME
261
+ }
262
+ },
263
+ parallel_tool_calls: false,
264
+ messages: [
265
+ { role: 'system', content: systemPrompt },
266
+ { role: 'user', content: userMessage }
267
+ ]
268
+ };
269
+ this.traceRequest('chat.completions.create.tools', toolPayload);
270
+ const completion = (await this.client.chat.completions.create(toolPayload));
271
+ this.traceResponse('chat.completions.create.tools', completion);
272
+ const toolCalls = completion.choices?.[0]?.message?.tool_calls;
273
+ parsed = this.parseQualificationToolCalls(toolCalls);
274
+ if (!parsed) {
275
+ parsed = this.parseQualificationContent(completion.choices?.[0]?.message?.content ?? '');
276
+ }
277
+ promptTokens = completion.usage?.prompt_tokens ?? 0;
278
+ completionTokens = completion.usage?.completion_tokens ?? 0;
279
+ if (!parsed && this.isTruncatedWithoutStructuredOutput(completion)) {
280
+ logger.warn(`Qualification tool-call truncated for model ${input.model}; retrying with max_tokens=${expandedMaxTokens}.`);
281
+ const retryToolPayload = {
282
+ model: input.model,
283
+ temperature: 0,
284
+ top_p: 1,
285
+ max_tokens: expandedMaxTokens,
286
+ tools: [QUALIFICATION_TOOL],
287
+ tool_choice: {
288
+ type: 'function',
289
+ function: {
290
+ name: QUALIFICATION_TOOL_NAME
291
+ }
292
+ },
293
+ parallel_tool_calls: false,
294
+ messages: [
295
+ {
296
+ role: 'system',
297
+ content: `${systemPrompt}\nReturn only the function arguments. Do not add any extra text.`
298
+ },
299
+ { role: 'user', content: userMessage }
300
+ ]
301
+ };
302
+ this.traceRequest('chat.completions.create.tools.retry', retryToolPayload);
303
+ const retryWithTools = (await this.client.chat.completions.create(retryToolPayload));
304
+ this.traceResponse('chat.completions.create.tools.retry', retryWithTools);
305
+ parsed = this.parseQualificationToolCalls(retryWithTools.choices?.[0]?.message?.tool_calls);
306
+ if (!parsed) {
307
+ parsed = this.parseQualificationContent(retryWithTools.choices?.[0]?.message?.content ?? '');
308
+ }
309
+ promptTokens += retryWithTools.usage?.prompt_tokens ?? 0;
310
+ completionTokens += retryWithTools.usage?.completion_tokens ?? 0;
311
+ }
312
+ }
313
+ if (!parsed) {
314
+ const jsonFallbackPayload = {
315
+ model: input.model,
316
+ temperature: 0,
317
+ top_p: 1,
318
+ max_tokens: Math.max(120, Math.min(baseMaxTokens, 400)),
319
+ response_format: {
320
+ type: 'json_object'
321
+ },
322
+ messages: [
323
+ {
324
+ role: 'system',
325
+ content: `${systemPrompt}\nOutput one compact JSON object only, with no markdown and no extra text.`
326
+ },
327
+ { role: 'user', content: userMessage }
328
+ ]
329
+ };
330
+ this.traceRequest('chat.completions.create.json_fallback', jsonFallbackPayload);
331
+ const retry = (await this.client.chat.completions.create(jsonFallbackPayload));
332
+ this.traceResponse('chat.completions.create.json_fallback', retry);
333
+ parsed = this.parseQualificationContent(retry.choices?.[0]?.message?.content ?? '');
334
+ promptTokens += retry.usage?.prompt_tokens ?? 0;
335
+ completionTokens += retry.usage?.completion_tokens ?? 0;
336
+ if (!parsed && this.isTruncatedWithoutStructuredOutput(retry)) {
337
+ logger.warn(`Qualification JSON fallback truncated for model ${input.model}; retrying with max_tokens=${expandedMaxTokens}.`);
338
+ const expandedJsonRetryPayload = {
339
+ model: input.model,
340
+ temperature: 0,
341
+ top_p: 1,
342
+ max_tokens: expandedMaxTokens,
343
+ response_format: {
344
+ type: 'json_object'
345
+ },
346
+ messages: [
347
+ {
348
+ role: 'system',
349
+ content: `${systemPrompt}\nOutput one compact JSON object only, with no markdown and no extra text.`
350
+ },
351
+ { role: 'user', content: userMessage }
352
+ ]
353
+ };
354
+ this.traceRequest('chat.completions.create.json_fallback.retry', expandedJsonRetryPayload);
355
+ const expandedJsonRetry = (await this.client.chat.completions.create(expandedJsonRetryPayload));
356
+ this.traceResponse('chat.completions.create.json_fallback.retry', expandedJsonRetry);
357
+ parsed = this.parseQualificationContent(expandedJsonRetry.choices?.[0]?.message?.content ?? '');
358
+ promptTokens += expandedJsonRetry.usage?.prompt_tokens ?? 0;
359
+ completionTokens += expandedJsonRetry.usage?.completion_tokens ?? 0;
360
+ }
361
+ }
362
+ if (!parsed) {
363
+ logger.warn(`Qualification output invalid after retries for model ${input.model}.`);
364
+ return {
365
+ qualified: false,
366
+ reason: 'Model output invalid; marked unqualified',
367
+ promptTokens,
368
+ completionTokens
369
+ };
370
+ }
371
+ return {
372
+ qualified: parsed.qualified,
373
+ reason: parsed.reason,
374
+ promptTokens,
375
+ completionTokens
376
+ };
377
+ }
378
+ catch (error) {
379
+ this.traceError('chat.completions.create', error);
380
+ throw toOpenRouterError(error);
381
+ }
382
+ }
383
+ isTruncatedWithoutStructuredOutput(completion) {
384
+ const choice = completion.choices?.[0];
385
+ if (!choice || choice.finish_reason !== 'length') {
386
+ return false;
387
+ }
388
+ const message = choice.message;
389
+ const hasContent = typeof message?.content === 'string' && message.content.trim().length > 0;
390
+ const hasToolArgs = Array.isArray(message?.tool_calls) &&
391
+ message.tool_calls.some((toolCall) => Boolean(toolCall.function?.arguments?.trim()));
392
+ return !hasContent && !hasToolArgs;
393
+ }
394
+ parseQualificationToolCalls(toolCalls) {
395
+ if (!toolCalls || toolCalls.length === 0) {
396
+ return null;
397
+ }
398
+ const qualificationToolCall = toolCalls.find((toolCall) => toolCall.type === 'function' && toolCall.function?.name === QUALIFICATION_TOOL_NAME);
399
+ const rawArgs = qualificationToolCall?.function?.arguments;
400
+ if (!rawArgs) {
401
+ return null;
402
+ }
403
+ try {
404
+ return qualifySchema.parse(parseStructuredJson(rawArgs));
405
+ }
406
+ catch {
407
+ const recovered = tryExtractQualification(rawArgs);
408
+ if (!recovered) {
409
+ return null;
410
+ }
411
+ try {
412
+ return qualifySchema.parse(recovered);
413
+ }
414
+ catch {
415
+ return null;
416
+ }
417
+ }
418
+ }
419
+ parseQualificationContent(raw) {
420
+ try {
421
+ return qualifySchema.parse(parseStructuredJson(raw));
422
+ }
423
+ catch {
424
+ const recovered = tryExtractQualification(raw);
425
+ if (!recovered) {
426
+ return null;
427
+ }
428
+ try {
429
+ return qualifySchema.parse(recovered);
430
+ }
431
+ catch {
432
+ return null;
433
+ }
434
+ }
435
+ }
436
+ }
437
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/services/openrouter/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function buildClarificationPrompt(criteria: string): string;
2
+ export declare function buildSpecPrompt(criteria: string, answers: Array<{
3
+ question: string;
4
+ answer: string;
5
+ }>): string;