@graphext/cuery 0.4.0 → 0.5.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.
Files changed (203) hide show
  1. package/esm/browser.d.ts +1 -1
  2. package/esm/browser.d.ts.map +1 -1
  3. package/esm/browser.js +1 -1
  4. package/esm/mod.d.ts +5 -2
  5. package/esm/mod.d.ts.map +1 -1
  6. package/esm/mod.js +7 -2
  7. package/esm/src/api.d.ts +36 -5
  8. package/esm/src/api.d.ts.map +1 -1
  9. package/esm/src/api.js +84 -37
  10. package/esm/src/apis/chatgptScraper/brightdata.js +1 -1
  11. package/esm/src/apis/chatgptScraper/oxy.js +1 -1
  12. package/esm/src/apis/chatgptScraper/scraper.js +2 -2
  13. package/esm/src/apis/hasdata/aim.js +1 -1
  14. package/esm/src/apis/hasdata/aio.js +1 -1
  15. package/esm/src/apis/hasdata/helpers.d.ts +1 -1
  16. package/esm/src/apis/hasdata/helpers.d.ts.map +1 -1
  17. package/esm/src/apis/hasdata/helpers.js +2 -2
  18. package/esm/src/assets/models.d.ts +60725 -0
  19. package/esm/src/assets/models.d.ts.map +1 -0
  20. package/esm/src/assets/models.js +71915 -0
  21. package/esm/src/helpers/async.d.ts.map +1 -0
  22. package/esm/src/{async.js → helpers/async.js} +1 -1
  23. package/esm/src/helpers/seedKeywords.d.ts.map +1 -0
  24. package/esm/src/helpers/urls.d.ts.map +1 -0
  25. package/esm/src/helpers/utils.d.ts.map +1 -0
  26. package/esm/src/llm.d.ts +35 -0
  27. package/esm/src/llm.d.ts.map +1 -0
  28. package/esm/src/llm.js +59 -0
  29. package/esm/src/providers/google.d.ts +12 -0
  30. package/esm/src/providers/google.d.ts.map +1 -0
  31. package/esm/src/providers/google.js +111 -0
  32. package/esm/src/providers/index.d.ts +13 -0
  33. package/esm/src/providers/index.d.ts.map +1 -0
  34. package/esm/src/providers/index.js +14 -0
  35. package/esm/src/providers/openai.d.ts +12 -0
  36. package/esm/src/providers/openai.d.ts.map +1 -0
  37. package/esm/src/providers/openai.js +141 -0
  38. package/esm/src/providers/pricing.d.ts +72 -0
  39. package/esm/src/providers/pricing.d.ts.map +1 -0
  40. package/esm/src/providers/pricing.js +88 -0
  41. package/esm/src/providers/registry.d.ts +20 -0
  42. package/esm/src/providers/registry.d.ts.map +1 -0
  43. package/esm/src/providers/registry.js +35 -0
  44. package/esm/src/providers/types.d.ts +49 -0
  45. package/esm/src/providers/types.d.ts.map +1 -0
  46. package/esm/src/providers/types.js +7 -0
  47. package/esm/src/response.d.ts +74 -0
  48. package/esm/src/response.d.ts.map +1 -0
  49. package/esm/src/response.js +110 -0
  50. package/esm/src/tool.d.ts +58 -0
  51. package/esm/src/tool.d.ts.map +1 -0
  52. package/esm/src/tool.js +91 -0
  53. package/esm/src/tools/brands.js +6 -6
  54. package/esm/src/tools/classifier.d.ts +80 -17
  55. package/esm/src/tools/classifier.d.ts.map +1 -1
  56. package/esm/src/tools/classifier.js +68 -80
  57. package/esm/src/tools/entities.d.ts +23 -12
  58. package/esm/src/tools/entities.d.ts.map +1 -1
  59. package/esm/src/tools/entities.js +27 -47
  60. package/esm/src/tools/funnel.js +7 -7
  61. package/esm/src/tools/generic.d.ts +17 -4
  62. package/esm/src/tools/generic.d.ts.map +1 -1
  63. package/esm/src/tools/generic.js +39 -14
  64. package/esm/src/tools/keywords.js +5 -5
  65. package/esm/src/tools/personas.d.ts +49 -2
  66. package/esm/src/tools/personas.d.ts.map +1 -1
  67. package/esm/src/tools/personas.js +59 -35
  68. package/esm/src/tools/scorer.d.ts +24 -6
  69. package/esm/src/tools/scorer.d.ts.map +1 -1
  70. package/esm/src/tools/scorer.js +27 -22
  71. package/esm/src/tools/search.d.ts.map +1 -1
  72. package/esm/src/tools/search.js +33 -9
  73. package/esm/src/tools/sentiment.d.ts +30 -8
  74. package/esm/src/tools/sentiment.d.ts.map +1 -1
  75. package/esm/src/tools/sentiment.js +33 -28
  76. package/esm/src/tools/sources.d.ts +5 -5
  77. package/esm/src/tools/sources.d.ts.map +1 -1
  78. package/esm/src/tools/sources.js +5 -6
  79. package/esm/src/tools/topics.d.ts +44 -16
  80. package/esm/src/tools/topics.d.ts.map +1 -1
  81. package/esm/src/tools/topics.js +77 -68
  82. package/esm/src/tools/translate.d.ts +22 -31
  83. package/esm/src/tools/translate.d.ts.map +1 -1
  84. package/esm/src/tools/translate.js +40 -36
  85. package/package.json +2 -1
  86. package/script/browser.d.ts +1 -1
  87. package/script/browser.d.ts.map +1 -1
  88. package/script/browser.js +1 -1
  89. package/script/mod.d.ts +5 -2
  90. package/script/mod.d.ts.map +1 -1
  91. package/script/mod.js +14 -2
  92. package/script/src/api.d.ts +36 -5
  93. package/script/src/api.d.ts.map +1 -1
  94. package/script/src/api.js +84 -35
  95. package/script/src/apis/chatgptScraper/brightdata.js +1 -1
  96. package/script/src/apis/chatgptScraper/oxy.js +1 -1
  97. package/script/src/apis/chatgptScraper/scraper.js +2 -2
  98. package/script/src/apis/hasdata/aim.js +1 -1
  99. package/script/src/apis/hasdata/aio.js +1 -1
  100. package/script/src/apis/hasdata/helpers.d.ts +1 -1
  101. package/script/src/apis/hasdata/helpers.d.ts.map +1 -1
  102. package/script/src/apis/hasdata/helpers.js +2 -2
  103. package/script/src/assets/models.d.ts +60725 -0
  104. package/script/src/assets/models.d.ts.map +1 -0
  105. package/script/src/assets/models.js +71917 -0
  106. package/script/src/helpers/async.d.ts.map +1 -0
  107. package/script/src/{async.js → helpers/async.js} +1 -1
  108. package/script/src/helpers/seedKeywords.d.ts.map +1 -0
  109. package/script/src/helpers/urls.d.ts.map +1 -0
  110. package/script/src/helpers/utils.d.ts.map +1 -0
  111. package/script/src/llm.d.ts +35 -0
  112. package/script/src/llm.d.ts.map +1 -0
  113. package/script/src/llm.js +65 -0
  114. package/script/src/providers/google.d.ts +12 -0
  115. package/script/src/providers/google.d.ts.map +1 -0
  116. package/script/src/providers/google.js +148 -0
  117. package/script/src/providers/index.d.ts +13 -0
  118. package/script/src/providers/index.d.ts.map +1 -0
  119. package/script/src/providers/index.js +24 -0
  120. package/script/src/providers/openai.d.ts +12 -0
  121. package/script/src/providers/openai.d.ts.map +1 -0
  122. package/script/src/providers/openai.js +181 -0
  123. package/script/src/providers/pricing.d.ts +72 -0
  124. package/script/src/providers/pricing.d.ts.map +1 -0
  125. package/script/src/providers/pricing.js +97 -0
  126. package/script/src/providers/registry.d.ts +20 -0
  127. package/script/src/providers/registry.d.ts.map +1 -0
  128. package/script/src/providers/registry.js +39 -0
  129. package/script/src/providers/types.d.ts +49 -0
  130. package/script/src/providers/types.d.ts.map +1 -0
  131. package/script/src/providers/types.js +8 -0
  132. package/script/src/response.d.ts +74 -0
  133. package/script/src/response.d.ts.map +1 -0
  134. package/script/src/response.js +114 -0
  135. package/script/src/tool.d.ts +58 -0
  136. package/script/src/tool.d.ts.map +1 -0
  137. package/script/src/tool.js +95 -0
  138. package/script/src/tools/brands.js +6 -6
  139. package/script/src/tools/classifier.d.ts +80 -17
  140. package/script/src/tools/classifier.d.ts.map +1 -1
  141. package/script/src/tools/classifier.js +72 -85
  142. package/script/src/tools/entities.d.ts +23 -12
  143. package/script/src/tools/entities.d.ts.map +1 -1
  144. package/script/src/tools/entities.js +29 -51
  145. package/script/src/tools/funnel.js +7 -7
  146. package/script/src/tools/generic.d.ts +17 -4
  147. package/script/src/tools/generic.d.ts.map +1 -1
  148. package/script/src/tools/generic.js +39 -14
  149. package/script/src/tools/keywords.js +5 -5
  150. package/script/src/tools/personas.d.ts +49 -2
  151. package/script/src/tools/personas.d.ts.map +1 -1
  152. package/script/src/tools/personas.js +63 -36
  153. package/script/src/tools/scorer.d.ts +24 -6
  154. package/script/src/tools/scorer.d.ts.map +1 -1
  155. package/script/src/tools/scorer.js +28 -24
  156. package/script/src/tools/search.d.ts.map +1 -1
  157. package/script/src/tools/search.js +69 -9
  158. package/script/src/tools/sentiment.d.ts +30 -8
  159. package/script/src/tools/sentiment.d.ts.map +1 -1
  160. package/script/src/tools/sentiment.js +37 -30
  161. package/script/src/tools/sources.d.ts +5 -5
  162. package/script/src/tools/sources.d.ts.map +1 -1
  163. package/script/src/tools/sources.js +4 -5
  164. package/script/src/tools/topics.d.ts +44 -16
  165. package/script/src/tools/topics.d.ts.map +1 -1
  166. package/script/src/tools/topics.js +80 -72
  167. package/script/src/tools/translate.d.ts +22 -31
  168. package/script/src/tools/translate.d.ts.map +1 -1
  169. package/script/src/tools/translate.js +43 -40
  170. package/esm/src/async.d.ts.map +0 -1
  171. package/esm/src/models.d.ts +0 -18
  172. package/esm/src/models.d.ts.map +0 -1
  173. package/esm/src/models.js +0 -48
  174. package/esm/src/openai.d.ts +0 -17
  175. package/esm/src/openai.d.ts.map +0 -1
  176. package/esm/src/openai.js +0 -136
  177. package/esm/src/tools/seedKeywords.d.ts.map +0 -1
  178. package/esm/src/urls.d.ts.map +0 -1
  179. package/esm/src/utils.d.ts.map +0 -1
  180. package/script/src/async.d.ts.map +0 -1
  181. package/script/src/models.d.ts +0 -18
  182. package/script/src/models.d.ts.map +0 -1
  183. package/script/src/models.js +0 -52
  184. package/script/src/openai.d.ts +0 -17
  185. package/script/src/openai.d.ts.map +0 -1
  186. package/script/src/openai.js +0 -175
  187. package/script/src/tools/seedKeywords.d.ts.map +0 -1
  188. package/script/src/urls.d.ts.map +0 -1
  189. package/script/src/utils.d.ts.map +0 -1
  190. /package/esm/src/{async.d.ts → helpers/async.d.ts} +0 -0
  191. /package/esm/src/{tools → helpers}/seedKeywords.d.ts +0 -0
  192. /package/esm/src/{tools → helpers}/seedKeywords.js +0 -0
  193. /package/esm/src/{urls.d.ts → helpers/urls.d.ts} +0 -0
  194. /package/esm/src/{urls.js → helpers/urls.js} +0 -0
  195. /package/esm/src/{utils.d.ts → helpers/utils.d.ts} +0 -0
  196. /package/esm/src/{utils.js → helpers/utils.js} +0 -0
  197. /package/script/src/{async.d.ts → helpers/async.d.ts} +0 -0
  198. /package/script/src/{tools → helpers}/seedKeywords.d.ts +0 -0
  199. /package/script/src/{tools → helpers}/seedKeywords.js +0 -0
  200. /package/script/src/{urls.d.ts → helpers/urls.d.ts} +0 -0
  201. /package/script/src/{urls.js → helpers/urls.js} +0 -0
  202. /package/script/src/{utils.d.ts → helpers/utils.d.ts} +0 -0
  203. /package/script/src/{utils.js → helpers/utils.js} +0 -0
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ /**
3
+ * Model pricing lookup and cost calculation.
4
+ *
5
+ * Pricing data is bundled from models.dev at build time.
6
+ * Run `deno task update-models` to refresh the data.
7
+ */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.lookupModel = lookupModel;
13
+ exports.getModelPricing = getModelPricing;
14
+ exports.getModelInfo = getModelInfo;
15
+ exports.calculateCost = calculateCost;
16
+ const models_js_1 = __importDefault(require("../assets/models.js"));
17
+ // Build flat index: model ID -> { provider, model }
18
+ const modelIndex = new Map();
19
+ for (const [providerId, provider] of Object.entries(models_js_1.default)) {
20
+ if (!provider.models)
21
+ continue;
22
+ for (const [modelId, model] of Object.entries(provider.models)) {
23
+ modelIndex.set(modelId, { provider: providerId, model });
24
+ }
25
+ }
26
+ /**
27
+ * Normalize a model ID by removing date suffixes and common variations.
28
+ */
29
+ function normalizeModel(modelId) {
30
+ return modelId.replace(/-\d{4}-\d{2}-\d{2}$/, '');
31
+ }
32
+ /**
33
+ * Look up a model entry by ID (with normalization fallback).
34
+ */
35
+ function lookupModel(modelId) {
36
+ return modelIndex.get(modelId) ?? modelIndex.get(normalizeModel(modelId)) ?? null;
37
+ }
38
+ /**
39
+ * Get pricing information for a model.
40
+ */
41
+ function getModelPricing(modelId) {
42
+ const entry = lookupModel(modelId);
43
+ if (!entry?.model.cost) {
44
+ return null;
45
+ }
46
+ const cost = entry.model.cost;
47
+ if (cost.input === 0 && cost.output === 0) {
48
+ return null;
49
+ }
50
+ return {
51
+ input: cost.input ?? 0,
52
+ output: cost.output ?? 0,
53
+ cacheRead: cost.cache_read,
54
+ cacheWrite: cost.cache_write,
55
+ reasoning: cost.reasoning,
56
+ };
57
+ }
58
+ /**
59
+ * Get full model information including pricing and capabilities.
60
+ */
61
+ function getModelInfo(modelId) {
62
+ const entry = lookupModel(modelId);
63
+ if (!entry) {
64
+ return null;
65
+ }
66
+ const { provider, model: m } = entry;
67
+ return {
68
+ id: m.id,
69
+ name: m.name,
70
+ provider,
71
+ pricing: getModelPricing(modelId),
72
+ contextLimit: m.limit?.context ?? null,
73
+ outputLimit: m.limit?.output ?? null,
74
+ capabilities: {
75
+ structuredOutput: m.structured_output ?? false,
76
+ toolCall: m.tool_call ?? false,
77
+ reasoning: m.reasoning ?? false,
78
+ },
79
+ };
80
+ }
81
+ /**
82
+ * Calculate cost for token usage.
83
+ */
84
+ function calculateCost(modelId, usage) {
85
+ const pricing = getModelPricing(modelId);
86
+ if (!pricing) {
87
+ return null;
88
+ }
89
+ const inputCost = (usage.inputTokens / 1_000_000) * pricing.input;
90
+ const outputCost = (usage.outputTokens / 1_000_000) * pricing.output;
91
+ return {
92
+ inputCost,
93
+ outputCost,
94
+ totalCost: inputCost + outputCost,
95
+ currency: 'USD',
96
+ };
97
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Provider registry - instantiates LLM providers by name or model ID.
3
+ */
4
+ import type { LLMProvider } from './types.js';
5
+ /**
6
+ * Get a provider by name.
7
+ * Creates a fresh provider instance each time to support different API keys.
8
+ * @param name - Provider name ('openai', 'google')
9
+ * @param apiKey - Optional API key. If not provided, uses environment variable.
10
+ */
11
+ export declare function getProvider(name: string, apiKey?: string): LLMProvider;
12
+ /**
13
+ * Get the appropriate provider for a model ID.
14
+ * Infers provider from model name prefix.
15
+ * Creates a fresh provider instance each time to support different API keys.
16
+ * @param modelId - Model identifier (e.g., 'gpt-4.1', 'gemini-2.0-flash')
17
+ * @param apiKey - Optional API key. If not provided, uses environment variable.
18
+ */
19
+ export declare function getProviderForModel(modelId: string, apiKey?: string): LLMProvider;
20
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/src/providers/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAQtE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CASjF"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /**
3
+ * Provider registry - instantiates LLM providers by name or model ID.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getProvider = getProvider;
7
+ exports.getProviderForModel = getProviderForModel;
8
+ const openai_js_1 = require("./openai.js");
9
+ const google_js_1 = require("./google.js");
10
+ /**
11
+ * Get a provider by name.
12
+ * Creates a fresh provider instance each time to support different API keys.
13
+ * @param name - Provider name ('openai', 'google')
14
+ * @param apiKey - Optional API key. If not provided, uses environment variable.
15
+ */
16
+ function getProvider(name, apiKey) {
17
+ switch (name) {
18
+ case 'google':
19
+ return new google_js_1.GoogleProvider(apiKey);
20
+ case 'openai':
21
+ default:
22
+ return new openai_js_1.OpenAIProvider(apiKey);
23
+ }
24
+ }
25
+ /**
26
+ * Get the appropriate provider for a model ID.
27
+ * Infers provider from model name prefix.
28
+ * Creates a fresh provider instance each time to support different API keys.
29
+ * @param modelId - Model identifier (e.g., 'gpt-4.1', 'gemini-2.0-flash')
30
+ * @param apiKey - Optional API key. If not provided, uses environment variable.
31
+ */
32
+ function getProviderForModel(modelId, apiKey) {
33
+ const modelLower = modelId.toLowerCase();
34
+ if (modelLower.startsWith('gemini')) {
35
+ return new google_js_1.GoogleProvider(apiKey);
36
+ }
37
+ // Default to OpenAI for gpt-*, o1-*, o3-*, and unknown models
38
+ return new openai_js_1.OpenAIProvider(apiKey);
39
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Core LLM types - provider-agnostic interfaces.
3
+ *
4
+ * This module is the foundation of the provider system.
5
+ * It has no dependencies on other modules to avoid circular imports.
6
+ */
7
+ import type { z } from '../../deps/jsr.io/@zod/zod/4.3.6/src/index.js';
8
+ import type { TokenUsage } from '../response.js';
9
+ /**
10
+ * A message in an LLM conversation.
11
+ */
12
+ export interface Message {
13
+ role: 'system' | 'user' | 'assistant';
14
+ content: string;
15
+ }
16
+ /**
17
+ * Response from an LLM provider.
18
+ */
19
+ export interface LLMResponse<T> {
20
+ parsed: T | null;
21
+ text: string | null;
22
+ usage: TokenUsage | null;
23
+ error: Error | null;
24
+ }
25
+ /**
26
+ * Provider-specific parameters passed through to the underlying API.
27
+ */
28
+ export type ProviderParams = Record<string, unknown>;
29
+ /**
30
+ * Interface for LLM providers.
31
+ */
32
+ export interface LLMProvider {
33
+ /** Provider name (e.g., 'openai', 'gemini') */
34
+ readonly name: string;
35
+ /**
36
+ * Make a completion request to the LLM.
37
+ *
38
+ * @param messages - The conversation messages
39
+ * @param model - The model identifier
40
+ * @param schema - Optional Zod schema for structured output
41
+ * @param params - Provider-specific parameters
42
+ */
43
+ complete<T>(messages: Message[], model: string, schema: z.ZodType<T> | null, params?: ProviderParams): Promise<LLMResponse<T>>;
44
+ }
45
+ /**
46
+ * Conversation type (array of messages).
47
+ */
48
+ export type LLMConversation = Message[];
49
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/providers/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,+CAA+C,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC7B,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;OAOG;IACH,QAAQ,CAAC,CAAC,EACT,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,EAC3B,MAAM,CAAC,EAAE,cAAc,GACrB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * Core LLM types - provider-agnostic interfaces.
4
+ *
5
+ * This module is the foundation of the provider system.
6
+ * It has no dependencies on other modules to avoid circular imports.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,74 @@
1
+ /**
2
+ * BatchResponse - A wrapper for batch LLM results with usage tracking.
3
+ *
4
+ * Provides an array-like interface for backwards compatibility while
5
+ * adding usage aggregation capabilities.
6
+ */
7
+ /**
8
+ * Token usage from a single LLM call.
9
+ */
10
+ export interface TokenUsage {
11
+ inputTokens: number;
12
+ outputTokens: number;
13
+ totalTokens: number;
14
+ }
15
+ /**
16
+ * Cost calculation result in USD.
17
+ */
18
+ export interface UsageCost {
19
+ inputCost: number;
20
+ outputCost: number;
21
+ totalCost: number;
22
+ currency: 'USD';
23
+ }
24
+ /**
25
+ * Aggregated usage across multiple LLM calls.
26
+ */
27
+ export interface AggregatedUsage {
28
+ tokens: TokenUsage;
29
+ cost: UsageCost | null;
30
+ callCount: number;
31
+ model: string | null;
32
+ }
33
+ /**
34
+ * A batch of LLM results with usage tracking.
35
+ *
36
+ * Implements Iterable<T> and provides array-like methods for backwards
37
+ * compatibility with code expecting Array<T>.
38
+ */
39
+ export declare class BatchResponse<T> implements Iterable<T> {
40
+ readonly results: ReadonlyArray<T>;
41
+ private readonly _tokenUsages;
42
+ private readonly _model;
43
+ constructor(results: T[], tokenUsages?: Array<TokenUsage | null | undefined>, model?: string);
44
+ get length(): number;
45
+ [Symbol.iterator](): Iterator<T>;
46
+ at(index: number): T | undefined;
47
+ map<U>(fn: (value: T, index: number) => U): BatchResponse<U>;
48
+ filter(fn: (value: T, index: number) => boolean): BatchResponse<T>;
49
+ forEach(fn: (value: T, index: number) => void): void;
50
+ find(fn: (value: T, index: number) => boolean): T | undefined;
51
+ findIndex(fn: (value: T, index: number) => boolean): number;
52
+ some(fn: (value: T, index: number) => boolean): boolean;
53
+ every(fn: (value: T, index: number) => boolean): boolean;
54
+ reduce<U>(fn: (acc: U, value: T, index: number) => U, initial: U): U;
55
+ /**
56
+ * Convert to a plain array.
57
+ */
58
+ toArray(): T[];
59
+ /**
60
+ * Get aggregated usage across all calls in this batch.
61
+ * Cost is calculated lazily only if model and costCalculator were provided.
62
+ * Returns null if usage tracking was not enabled.
63
+ */
64
+ usage(): AggregatedUsage | null;
65
+ /**
66
+ * Get token usage for a specific index.
67
+ */
68
+ usageAt(index: number): TokenUsage | undefined;
69
+ /**
70
+ * Check if any usage info is available.
71
+ */
72
+ hasUsage(): boolean;
73
+ }
74
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/src/response.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;;;GAKG;AACH,qBAAa,aAAa,CAAC,CAAC,CAAE,YAAW,QAAQ,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuC;IACpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAGtC,OAAO,EAAE,CAAC,EAAE,EACZ,WAAW,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM;IAUf,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC;IAIhC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAIhC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAK5D,MAAM,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC;IAclE,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIpD,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,CAAC,GAAG,SAAS;IAI7D,SAAS,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM;IAI3D,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO;IAIvD,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO;IAIxD,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC;IAIpE;;OAEG;IACH,OAAO,IAAI,CAAC,EAAE;IAMd;;;;OAIG;IACH,KAAK,IAAI,eAAe,GAAG,IAAI;IAwB/B;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI9C;;OAEG;IACH,QAAQ,IAAI,OAAO;CAGnB"}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /**
3
+ * BatchResponse - A wrapper for batch LLM results with usage tracking.
4
+ *
5
+ * Provides an array-like interface for backwards compatibility while
6
+ * adding usage aggregation capabilities.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.BatchResponse = void 0;
10
+ const pricing_js_1 = require("./providers/pricing.js");
11
+ /**
12
+ * A batch of LLM results with usage tracking.
13
+ *
14
+ * Implements Iterable<T> and provides array-like methods for backwards
15
+ * compatibility with code expecting Array<T>.
16
+ */
17
+ class BatchResponse {
18
+ results;
19
+ _tokenUsages;
20
+ _model;
21
+ constructor(results, tokenUsages, model) {
22
+ this.results = results;
23
+ // Normalize null to undefined for internal storage, or null if not provided
24
+ this._tokenUsages = tokenUsages ? tokenUsages.map(u => u ?? undefined) : null;
25
+ this._model = model ?? null;
26
+ }
27
+ // Array-like interface
28
+ get length() {
29
+ return this.results.length;
30
+ }
31
+ [Symbol.iterator]() {
32
+ return this.results[Symbol.iterator]();
33
+ }
34
+ at(index) {
35
+ return this.results.at(index);
36
+ }
37
+ map(fn) {
38
+ const mapped = this.results.map((item, i) => fn(item, i));
39
+ return new BatchResponse(mapped, this._tokenUsages ?? undefined, this._model ?? undefined);
40
+ }
41
+ filter(fn) {
42
+ const filtered = [];
43
+ const usages = this._tokenUsages ? [] : undefined;
44
+ this.results.forEach((item, i) => {
45
+ if (fn(item, i)) {
46
+ filtered.push(item);
47
+ usages?.push(this._tokenUsages[i]);
48
+ }
49
+ });
50
+ return new BatchResponse(filtered, usages, this._model ?? undefined);
51
+ }
52
+ forEach(fn) {
53
+ this.results.forEach(fn);
54
+ }
55
+ find(fn) {
56
+ return this.results.find(fn);
57
+ }
58
+ findIndex(fn) {
59
+ return this.results.findIndex(fn);
60
+ }
61
+ some(fn) {
62
+ return this.results.some(fn);
63
+ }
64
+ every(fn) {
65
+ return this.results.every(fn);
66
+ }
67
+ reduce(fn, initial) {
68
+ return this.results.reduce(fn, initial);
69
+ }
70
+ /**
71
+ * Convert to a plain array.
72
+ */
73
+ toArray() {
74
+ return [...this.results];
75
+ }
76
+ // Usage tracking
77
+ /**
78
+ * Get aggregated usage across all calls in this batch.
79
+ * Cost is calculated lazily only if model and costCalculator were provided.
80
+ * Returns null if usage tracking was not enabled.
81
+ */
82
+ usage() {
83
+ if (!this._tokenUsages) {
84
+ return null;
85
+ }
86
+ const valid = this._tokenUsages.filter((u) => u !== undefined);
87
+ const aggregatedTokens = {
88
+ inputTokens: valid.reduce((sum, u) => sum + u.inputTokens, 0),
89
+ outputTokens: valid.reduce((sum, u) => sum + u.outputTokens, 0),
90
+ totalTokens: valid.reduce((sum, u) => sum + u.totalTokens, 0),
91
+ };
92
+ // Calculate cost if we have a model
93
+ const cost = this._model ? (0, pricing_js_1.calculateCost)(this._model, aggregatedTokens) : null;
94
+ return {
95
+ tokens: aggregatedTokens,
96
+ cost,
97
+ callCount: valid.length,
98
+ model: this._model,
99
+ };
100
+ }
101
+ /**
102
+ * Get token usage for a specific index.
103
+ */
104
+ usageAt(index) {
105
+ return this._tokenUsages?.[index];
106
+ }
107
+ /**
108
+ * Check if any usage info is available.
109
+ */
110
+ hasUsage() {
111
+ return this._tokenUsages?.some((u) => u !== undefined) ?? false;
112
+ }
113
+ }
114
+ exports.BatchResponse = BatchResponse;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Tool abstraction for LLM-powered operations.
3
+ *
4
+ * Provides a base class for building tools with consistent
5
+ * single-item and batch processing, usage tracking, and error handling.
6
+ */
7
+ import type { z } from '../deps/jsr.io/@zod/zod/4.3.6/src/index.js';
8
+ import { type LLMResponse, type Message, type ProviderParams } from './llm.js';
9
+ import { BatchResponse } from './response.js';
10
+ /**
11
+ * Configuration for LLM calls. Can be overridden per-invocation.
12
+ */
13
+ export interface ModelConfig {
14
+ /** The model to use */
15
+ model: string;
16
+ /** Provider-specific parameters */
17
+ modelParams?: ProviderParams;
18
+ /** Maximum retry attempts (default: 3) */
19
+ maxRetries?: number;
20
+ /** Max concurrent requests for batch (default: 100) */
21
+ maxConcurrency?: number;
22
+ /** Enable cost tracking for batch (default: false) */
23
+ trackCost?: boolean;
24
+ /** Throw an error instead of returning null on failure (default: false) */
25
+ throwOnFailure?: boolean;
26
+ }
27
+ /**
28
+ * Abstract base class for LLM-powered tools.
29
+ */
30
+ export declare abstract class Tool<TInput, TOutput, TResult = TOutput> {
31
+ protected readonly modelConfig: ModelConfig;
32
+ constructor(modelConfig: ModelConfig);
33
+ /**
34
+ * Define the Zod schema for LLM response validation.
35
+ * Override this to provide structured output validation.
36
+ *
37
+ * Returns null by default for raw text mode.
38
+ * When returning null, TOutput must be `string`.
39
+ *
40
+ * Make this as cheap as possible, as it's called on every invocation (row).
41
+ * E.g. by preparing it in the constructor if it doesn't depend on input.
42
+ */
43
+ protected schema(): z.ZodType<TOutput> | null;
44
+ /** Build the prompt from a single input
45
+ * Make this as cheap as possible, as it's called on every invocation (row).
46
+ * E.g. by preparing it in the constructor if it doesn't depend on input.
47
+ */
48
+ protected abstract prompt(input: TInput): string | Message[];
49
+ /** Extract final result from parsed output. Override to transform. */
50
+ protected extractResult(parsed: TOutput): TResult;
51
+ /** Check if input should be skipped (returns null without LLM call) */
52
+ protected isEmpty(input: TInput): boolean;
53
+ /** Process a single input */
54
+ invoke(input: TInput, options?: Partial<ModelConfig>): Promise<LLMResponse<TResult | null>>;
55
+ /** Process multiple inputs with usage tracking */
56
+ batch(inputs: TInput[], options?: Partial<ModelConfig>): Promise<BatchResponse<TResult | null>>;
57
+ }
58
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/src/tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,4CAA4C,CAAC;AACpE,OAAO,EAAc,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAE3F,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,WAAW,CAAC,EAAE,cAAc,CAAC;IAC7B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AASD;;GAEG;AACH,8BAAsB,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO;IAC5D,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;gBAEhC,WAAW,EAAE,WAAW;IAIpC;;;;;;;;;OASG;IACH,SAAS,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAI7C;;;MAGE;IACF,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE;IAE5D,sEAAsE;IACtE,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;IAIjD,uEAAuE;IACvE,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAOzC,6BAA6B;IACvB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAmCrG,kDAAkD;IAC5C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAiBzG"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ /**
3
+ * Tool abstraction for LLM-powered operations.
4
+ *
5
+ * Provides a base class for building tools with consistent
6
+ * single-item and batch processing, usage tracking, and error handling.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.Tool = void 0;
10
+ const llm_js_1 = require("./llm.js");
11
+ const async_js_1 = require("./helpers/async.js");
12
+ const response_js_1 = require("./response.js");
13
+ const DEFAULTS = {
14
+ maxRetries: 3,
15
+ maxConcurrency: 100,
16
+ trackCost: false,
17
+ throwOnFailure: false,
18
+ };
19
+ /**
20
+ * Abstract base class for LLM-powered tools.
21
+ */
22
+ class Tool {
23
+ modelConfig;
24
+ constructor(modelConfig) {
25
+ this.modelConfig = modelConfig;
26
+ }
27
+ /**
28
+ * Define the Zod schema for LLM response validation.
29
+ * Override this to provide structured output validation.
30
+ *
31
+ * Returns null by default for raw text mode.
32
+ * When returning null, TOutput must be `string`.
33
+ *
34
+ * Make this as cheap as possible, as it's called on every invocation (row).
35
+ * E.g. by preparing it in the constructor if it doesn't depend on input.
36
+ */
37
+ schema() {
38
+ return null;
39
+ }
40
+ /** Extract final result from parsed output. Override to transform. */
41
+ extractResult(parsed) {
42
+ return parsed;
43
+ }
44
+ /** Check if input should be skipped (returns null without LLM call) */
45
+ isEmpty(input) {
46
+ if (input == null)
47
+ return true;
48
+ if (typeof input === 'string' && input.trim() === '')
49
+ return true;
50
+ if (typeof input === 'object' && Object.keys(input).length === 0)
51
+ return true;
52
+ return false;
53
+ }
54
+ /** Process a single input */
55
+ async invoke(input, options = {}) {
56
+ if (this.isEmpty(input)) {
57
+ return { parsed: null, text: null, usage: null, error: null };
58
+ }
59
+ const { model, modelParams, maxRetries, throwOnFailure } = { ...DEFAULTS, ...this.modelConfig, ...options };
60
+ const response = await (0, llm_js_1.askLLMSafe)({
61
+ prompt: this.prompt(input),
62
+ model,
63
+ schema: this.schema(),
64
+ params: modelParams,
65
+ maxRetries,
66
+ onError: 'return',
67
+ });
68
+ if (response.error != null || response.parsed == null) {
69
+ if (throwOnFailure) {
70
+ throw response.error ?? new Error('LLM call failed to produce a result');
71
+ }
72
+ return { parsed: null, text: response.text, usage: response.usage, error: response.error };
73
+ }
74
+ // Type assertion: when schema() returns null, askLLMSafe returns string,
75
+ // which should match TOutput (caller's responsibility to set TOutput = string)
76
+ const parsed = response.parsed;
77
+ return {
78
+ parsed: this.extractResult(parsed),
79
+ text: response.text,
80
+ usage: response.usage,
81
+ error: null,
82
+ };
83
+ }
84
+ /** Process multiple inputs with usage tracking */
85
+ async batch(inputs, options = {}) {
86
+ const { model, modelParams, maxRetries, maxConcurrency, trackCost } = {
87
+ ...DEFAULTS,
88
+ ...this.modelConfig,
89
+ ...options,
90
+ };
91
+ const responses = await (0, async_js_1.mapParallel)(inputs, maxConcurrency, (input) => this.invoke(input, { model, modelParams, maxRetries }));
92
+ return new response_js_1.BatchResponse(responses.map((r) => r.parsed), trackCost ? responses.map((r) => r.usage) : undefined, trackCost ? model : undefined);
93
+ }
94
+ }
95
+ exports.Tool = Tool;
@@ -11,12 +11,12 @@ exports.createBrandMatchKey = createBrandMatchKey;
11
11
  exports.rankBrandsInText = rankBrandsInText;
12
12
  exports.rankBrandsInTexts = rankBrandsInTexts;
13
13
  const index_js_1 = require("../../deps/jsr.io/@zod/zod/4.3.6/src/index.js");
14
- const async_js_1 = require("../async.js");
15
- const openai_js_1 = require("../openai.js");
14
+ const async_js_1 = require("../helpers/async.js");
15
+ const llm_js_1 = require("../llm.js");
16
16
  const brand_schema_js_1 = require("../schemas/brand.schema.js");
17
17
  const search_js_1 = require("./search.js");
18
- const utils_js_1 = require("../utils.js");
19
- const urls_js_1 = require("../urls.js");
18
+ const utils_js_1 = require("../helpers/utils.js");
19
+ const urls_js_1 = require("../helpers/urls.js");
20
20
  function buildBrandContext({ brand, brandDomain, sector, market, briefing }) {
21
21
  let brandContext;
22
22
  if (brandDomain) {
@@ -160,9 +160,9 @@ async function generatePortfolioKeywords(product, sector, market, language = 'en
160
160
  .replaceAll('{sector}', sector)
161
161
  .replaceAll('{market}', market)
162
162
  .replaceAll('{language}', language);
163
- const { parsed } = await (0, openai_js_1.askOpenAISafe)(prompt, model, PortfolioKeywordsSchema);
163
+ const { parsed } = await (0, llm_js_1.askLLMSafe)({ prompt, model, schema: PortfolioKeywordsSchema });
164
164
  if (!parsed) {
165
- throw new Error('Failed to parse portfolio keywords from OpenAI response');
165
+ throw new Error('Failed to parse portfolio keywords from LLM response');
166
166
  }
167
167
  return parsed.keywords;
168
168
  }