@riotprompt/execution-gemini 0.0.4 → 1.0.1-dev.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/README.md CHANGED
@@ -78,3 +78,5 @@ interface ProviderResponse {
78
78
  ## License
79
79
 
80
80
  Apache-2.0
81
+
82
+ <!-- v1.0.0 -->
package/dist/index.js CHANGED
@@ -1,4 +1,32 @@
1
1
  import { GoogleGenerativeAI } from "@google/generative-ai";
2
+ import { getRedactor } from "@theunwalked/offrecord";
3
+ import { configureErrorSanitizer, configureSecretGuard, createSafeError } from "@theunwalked/spotclean";
4
+ const redactor = getRedactor();
5
+ redactor.register({
6
+ name: "gemini",
7
+ patterns: [
8
+ /AIza[a-zA-Z0-9_-]{35}/g
9
+ ],
10
+ validator: (key) => /^AIza[a-zA-Z0-9_-]{35}$/.test(key),
11
+ envVar: "GEMINI_API_KEY",
12
+ description: "Google Gemini API keys"
13
+ });
14
+ configureErrorSanitizer({
15
+ enabled: true,
16
+ environment: process.env.NODE_ENV === "production" ? "production" : "development",
17
+ includeCorrelationId: true,
18
+ sanitizeStackTraces: process.env.NODE_ENV === "production",
19
+ maxMessageLength: 500
20
+ });
21
+ configureSecretGuard({
22
+ enabled: true,
23
+ redactionText: "[REDACTED]",
24
+ preservePartial: false,
25
+ preserveLength: 0,
26
+ customPatterns: [
27
+ { name: "gemini", pattern: /AIza[a-zA-Z0-9_-]{35}/g, description: "Google Gemini API key" }
28
+ ]
29
+ });
2
30
  class GeminiProvider {
3
31
  name = "gemini";
4
32
  /**
@@ -13,79 +41,89 @@ class GeminiProvider {
13
41
  */
14
42
  async execute(request, options = {}) {
15
43
  const apiKey = options.apiKey || process.env.GEMINI_API_KEY;
16
- if (!apiKey) throw new Error("Gemini API key is required");
17
- const genAI = new GoogleGenerativeAI(apiKey);
18
- const modelName = options.model || request.model || "gemini-1.5-pro";
19
- const generationConfig = {};
20
- if (request.responseFormat?.type === "json_schema") {
21
- generationConfig.responseMimeType = "application/json";
22
- const openAISchema = request.responseFormat.json_schema.schema;
23
- const mapSchema = (s) => {
24
- if (!s) return void 0;
25
- const newSchema = { ...s };
26
- if (newSchema.type) {
27
- newSchema.type = typeof newSchema.type === "string" ? newSchema.type.toUpperCase() : newSchema.type;
28
- }
29
- if (newSchema.properties) {
30
- const newProps = {};
31
- for (const [key, val] of Object.entries(newSchema.properties)) {
32
- newProps[key] = mapSchema(val);
44
+ if (!apiKey) {
45
+ throw new Error("Gemini API key is required. Set GEMINI_API_KEY environment variable.");
46
+ }
47
+ const validation = redactor.validateKey(apiKey, "gemini");
48
+ if (!validation.valid) {
49
+ throw new Error("Invalid Gemini API key format");
50
+ }
51
+ try {
52
+ const genAI = new GoogleGenerativeAI(apiKey);
53
+ const modelName = options.model || request.model || "gemini-1.5-pro";
54
+ const generationConfig = {};
55
+ if (request.responseFormat?.type === "json_schema") {
56
+ generationConfig.responseMimeType = "application/json";
57
+ const openAISchema = request.responseFormat.json_schema.schema;
58
+ const mapSchema = (s) => {
59
+ if (!s) return void 0;
60
+ const newSchema = { ...s };
61
+ if (newSchema.type) {
62
+ newSchema.type = typeof newSchema.type === "string" ? newSchema.type.toUpperCase() : newSchema.type;
63
+ }
64
+ if (newSchema.properties) {
65
+ const newProps = {};
66
+ for (const [key, val] of Object.entries(newSchema.properties)) {
67
+ newProps[key] = mapSchema(val);
68
+ }
69
+ newSchema.properties = newProps;
33
70
  }
34
- newSchema.properties = newProps;
71
+ if (newSchema.items) {
72
+ newSchema.items = mapSchema(newSchema.items);
73
+ }
74
+ delete newSchema.additionalProperties;
75
+ delete newSchema["$schema"];
76
+ return newSchema;
77
+ };
78
+ generationConfig.responseSchema = mapSchema(openAISchema);
79
+ }
80
+ let systemInstruction = "";
81
+ for (const msg of request.messages) {
82
+ if (msg.role === "system" || msg.role === "developer") {
83
+ systemInstruction += (typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content)) + "\n\n";
35
84
  }
36
- if (newSchema.items) {
37
- newSchema.items = mapSchema(newSchema.items);
85
+ }
86
+ const configuredModel = genAI.getGenerativeModel({
87
+ model: modelName,
88
+ systemInstruction: systemInstruction ? systemInstruction.trim() : void 0,
89
+ generationConfig
90
+ });
91
+ const chatHistory = [];
92
+ let lastUserMessage = "";
93
+ for (const msg of request.messages) {
94
+ if (msg.role === "system" || msg.role === "developer") continue;
95
+ const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
96
+ if (msg.role === "user") {
97
+ lastUserMessage = content;
38
98
  }
39
- delete newSchema.additionalProperties;
40
- delete newSchema["$schema"];
41
- return newSchema;
42
- };
43
- generationConfig.responseSchema = mapSchema(openAISchema);
44
- }
45
- let systemInstruction = "";
46
- for (const msg of request.messages) {
47
- if (msg.role === "system" || msg.role === "developer") {
48
- systemInstruction += (typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content)) + "\n\n";
99
+ chatHistory.push({
100
+ role: msg.role === "assistant" ? "model" : "user",
101
+ parts: [{ text: content }]
102
+ });
49
103
  }
50
- }
51
- const configuredModel = genAI.getGenerativeModel({
52
- model: modelName,
53
- systemInstruction: systemInstruction ? systemInstruction.trim() : void 0,
54
- generationConfig
55
- });
56
- const chatHistory = [];
57
- let lastUserMessage = "";
58
- for (const msg of request.messages) {
59
- if (msg.role === "system" || msg.role === "developer") continue;
60
- const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
61
- if (msg.role === "user") {
62
- lastUserMessage = content;
104
+ let result;
105
+ if (chatHistory.length > 1) {
106
+ const lastMsg = chatHistory.pop();
107
+ const chat = configuredModel.startChat({
108
+ history: chatHistory
109
+ });
110
+ result = await chat.sendMessage(lastMsg?.parts[0].text || "");
111
+ } else {
112
+ result = await configuredModel.generateContent(lastUserMessage || " ");
63
113
  }
64
- chatHistory.push({
65
- role: msg.role === "assistant" ? "model" : "user",
66
- parts: [{ text: content }]
67
- });
68
- }
69
- let result;
70
- if (chatHistory.length > 1) {
71
- const lastMsg = chatHistory.pop();
72
- const chat = configuredModel.startChat({
73
- history: chatHistory
74
- });
75
- result = await chat.sendMessage(lastMsg?.parts[0].text || "");
76
- } else {
77
- result = await configuredModel.generateContent(lastUserMessage || " ");
114
+ const response = await result.response;
115
+ const text = response.text();
116
+ return {
117
+ content: text,
118
+ model: modelName,
119
+ usage: response.usageMetadata ? {
120
+ inputTokens: response.usageMetadata.promptTokenCount,
121
+ outputTokens: response.usageMetadata.candidatesTokenCount
122
+ } : void 0
123
+ };
124
+ } catch (error) {
125
+ throw createSafeError(error, { provider: "gemini" });
78
126
  }
79
- const response = await result.response;
80
- const text = response.text();
81
- return {
82
- content: text,
83
- model: modelName,
84
- usage: response.usageMetadata ? {
85
- inputTokens: response.usageMetadata.promptTokenCount,
86
- outputTokens: response.usageMetadata.candidatesTokenCount
87
- } : void 0
88
- };
89
127
  }
90
128
  }
91
129
  function createGeminiProvider() {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Execution Gemini Package\n *\n * Google Gemini provider implementation for LLM execution.\n *\n * @packageDocumentation\n */\n\nimport { GoogleGenerativeAI } from '@google/generative-ai';\n\n// ===== INLINE TYPES (from 'execution' package) =====\n\nexport type Model = string;\n\nexport interface Message {\n role: 'user' | 'assistant' | 'system' | 'developer' | 'tool';\n content: string | string[] | null;\n name?: string;\n}\n\nexport interface Request {\n messages: Message[];\n model: Model;\n responseFormat?: any;\n validator?: any;\n addMessage(message: Message): void;\n}\n\nexport interface ProviderResponse {\n content: string;\n model: string;\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n toolCalls?: Array<{\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }>;\n}\n\nexport interface ExecutionOptions {\n apiKey?: string;\n model?: string;\n temperature?: number;\n maxTokens?: number;\n timeout?: number;\n retries?: number;\n}\n\nexport interface Provider {\n readonly name: string;\n execute(request: Request, options?: ExecutionOptions): Promise<ProviderResponse>;\n supportsModel?(model: Model): boolean;\n}\n\n/**\n * Gemini Provider implementation\n */\nexport class GeminiProvider implements Provider {\n readonly name = 'gemini';\n\n /**\n * Check if this provider supports a given model\n */\n supportsModel(model: Model): boolean {\n if (!model) return false;\n return model.startsWith('gemini');\n }\n\n /**\n * Execute a request against Gemini\n */\n async execute(\n request: Request,\n options: ExecutionOptions = {}\n ): Promise<ProviderResponse> {\n const apiKey = options.apiKey || process.env.GEMINI_API_KEY;\n if (!apiKey) throw new Error('Gemini API key is required');\n\n const genAI = new GoogleGenerativeAI(apiKey);\n\n const modelName = options.model || request.model || 'gemini-1.5-pro';\n\n // Handle generation config for structured output\n const generationConfig: any = {};\n\n if (request.responseFormat?.type === 'json_schema') {\n generationConfig.responseMimeType = 'application/json';\n\n const openAISchema = request.responseFormat.json_schema.schema;\n\n // Map schema types to uppercase for Gemini\n const mapSchema = (s: any): any => {\n if (!s) return undefined;\n\n const newSchema: any = { ...s };\n\n if (newSchema.type) {\n newSchema.type =\n typeof newSchema.type === 'string'\n ? (newSchema.type as string).toUpperCase()\n : newSchema.type;\n }\n\n if (newSchema.properties) {\n const newProps: any = {};\n for (const [key, val] of Object.entries(newSchema.properties)) {\n newProps[key] = mapSchema(val);\n }\n newSchema.properties = newProps;\n }\n\n if (newSchema.items) {\n newSchema.items = mapSchema(newSchema.items);\n }\n\n delete newSchema.additionalProperties;\n delete newSchema['$schema'];\n\n return newSchema;\n };\n\n generationConfig.responseSchema = mapSchema(openAISchema);\n }\n\n // Extract system instruction\n let systemInstruction = '';\n\n for (const msg of request.messages) {\n if (msg.role === 'system' || msg.role === 'developer') {\n systemInstruction +=\n (typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content)) + '\\n\\n';\n }\n }\n\n const configuredModel = genAI.getGenerativeModel({\n model: modelName,\n systemInstruction: systemInstruction\n ? systemInstruction.trim()\n : undefined,\n generationConfig,\n });\n\n // Build history/messages\n const chatHistory = [];\n let lastUserMessage = '';\n\n for (const msg of request.messages) {\n if (msg.role === 'system' || msg.role === 'developer') continue;\n\n const content =\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content);\n\n if (msg.role === 'user') {\n lastUserMessage = content;\n }\n\n chatHistory.push({\n role: msg.role === 'assistant' ? 'model' : 'user',\n parts: [{ text: content }],\n });\n }\n\n let result;\n\n if (chatHistory.length > 1) {\n const lastMsg = chatHistory.pop();\n const chat = configuredModel.startChat({\n history: chatHistory,\n });\n result = await chat.sendMessage(lastMsg?.parts[0].text || '');\n } else {\n result = await configuredModel.generateContent(lastUserMessage || ' ');\n }\n\n const response = await result.response;\n const text = response.text();\n\n return {\n content: text,\n model: modelName,\n usage: response.usageMetadata\n ? {\n inputTokens: response.usageMetadata.promptTokenCount,\n outputTokens: response.usageMetadata.candidatesTokenCount,\n }\n : undefined,\n };\n }\n}\n\n/**\n * Create a new Gemini provider instance\n */\nexport function createGeminiProvider(): GeminiProvider {\n return new GeminiProvider();\n}\n\n/**\n * Package version\n */\nexport const VERSION = '0.0.1';\n\nexport default GeminiProvider;\n"],"names":[],"mappings":";AA+DO,MAAM,eAAmC;AAAA,EACnC,OAAO;AAAA;AAAA;AAAA;AAAA,EAKhB,cAAc,OAAuB;AACjC,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,MAAM,WAAW,QAAQ;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QACF,SACA,UAA4B,IACH;AACzB,UAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAC7C,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,4BAA4B;AAEzD,UAAM,QAAQ,IAAI,mBAAmB,MAAM;AAE3C,UAAM,YAAY,QAAQ,SAAS,QAAQ,SAAS;AAGpD,UAAM,mBAAwB,CAAA;AAE9B,QAAI,QAAQ,gBAAgB,SAAS,eAAe;AAChD,uBAAiB,mBAAmB;AAEpC,YAAM,eAAe,QAAQ,eAAe,YAAY;AAGxD,YAAM,YAAY,CAAC,MAAgB;AAC/B,YAAI,CAAC,EAAG,QAAO;AAEf,cAAM,YAAiB,EAAE,GAAG,EAAA;AAE5B,YAAI,UAAU,MAAM;AAChB,oBAAU,OACN,OAAO,UAAU,SAAS,WACnB,UAAU,KAAgB,gBAC3B,UAAU;AAAA,QACxB;AAEA,YAAI,UAAU,YAAY;AACtB,gBAAM,WAAgB,CAAA;AACtB,qBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,UAAU,UAAU,GAAG;AAC3D,qBAAS,GAAG,IAAI,UAAU,GAAG;AAAA,UACjC;AACA,oBAAU,aAAa;AAAA,QAC3B;AAEA,YAAI,UAAU,OAAO;AACjB,oBAAU,QAAQ,UAAU,UAAU,KAAK;AAAA,QAC/C;AAEA,eAAO,UAAU;AACjB,eAAO,UAAU,SAAS;AAE1B,eAAO;AAAA,MACX;AAEA,uBAAiB,iBAAiB,UAAU,YAAY;AAAA,IAC5D;AAGA,QAAI,oBAAoB;AAExB,eAAW,OAAO,QAAQ,UAAU;AAChC,UAAI,IAAI,SAAS,YAAY,IAAI,SAAS,aAAa;AACnD,8BACK,OAAO,IAAI,YAAY,WAClB,IAAI,UACJ,KAAK,UAAU,IAAI,OAAO,KAAK;AAAA,MAC7C;AAAA,IACJ;AAEA,UAAM,kBAAkB,MAAM,mBAAmB;AAAA,MAC7C,OAAO;AAAA,MACP,mBAAmB,oBACb,kBAAkB,KAAA,IAClB;AAAA,MACN;AAAA,IAAA,CACH;AAGD,UAAM,cAAc,CAAA;AACpB,QAAI,kBAAkB;AAEtB,eAAW,OAAO,QAAQ,UAAU;AAChC,UAAI,IAAI,SAAS,YAAY,IAAI,SAAS,YAAa;AAEvD,YAAM,UACF,OAAO,IAAI,YAAY,WACjB,IAAI,UACJ,KAAK,UAAU,IAAI,OAAO;AAEpC,UAAI,IAAI,SAAS,QAAQ;AACrB,0BAAkB;AAAA,MACtB;AAEA,kBAAY,KAAK;AAAA,QACb,MAAM,IAAI,SAAS,cAAc,UAAU;AAAA,QAC3C,OAAO,CAAC,EAAE,MAAM,SAAS;AAAA,MAAA,CAC5B;AAAA,IACL;AAEA,QAAI;AAEJ,QAAI,YAAY,SAAS,GAAG;AACxB,YAAM,UAAU,YAAY,IAAA;AAC5B,YAAM,OAAO,gBAAgB,UAAU;AAAA,QACnC,SAAS;AAAA,MAAA,CACZ;AACD,eAAS,MAAM,KAAK,YAAY,SAAS,MAAM,CAAC,EAAE,QAAQ,EAAE;AAAA,IAChE,OAAO;AACH,eAAS,MAAM,gBAAgB,gBAAgB,mBAAmB,GAAG;AAAA,IACzE;AAEA,UAAM,WAAW,MAAM,OAAO;AAC9B,UAAM,OAAO,SAAS,KAAA;AAEtB,WAAO;AAAA,MACH,SAAS;AAAA,MACT,OAAO;AAAA,MACP,OAAO,SAAS,gBACV;AAAA,QACE,aAAa,SAAS,cAAc;AAAA,QACpC,cAAc,SAAS,cAAc;AAAA,MAAA,IAEvC;AAAA,IAAA;AAAA,EAEd;AACJ;AAKO,SAAS,uBAAuC;AACnD,SAAO,IAAI,eAAA;AACf;AAKO,MAAM,UAAU;"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Execution Gemini Package\n *\n * Google Gemini provider implementation for LLM execution.\n *\n * @packageDocumentation\n */\n\nimport { GoogleGenerativeAI } from '@google/generative-ai';\nimport { getRedactor } from '@theunwalked/offrecord';\nimport { \n createSafeError, \n configureErrorSanitizer,\n configureSecretGuard,\n} from '@theunwalked/spotclean';\n\n// Register Gemini API key patterns on module load\nconst redactor = getRedactor();\nredactor.register({\n name: 'gemini',\n patterns: [\n /AIza[a-zA-Z0-9_-]{35}/g,\n ],\n validator: (key: string) => /^AIza[a-zA-Z0-9_-]{35}$/.test(key),\n envVar: 'GEMINI_API_KEY',\n description: 'Google Gemini API keys',\n});\n\n// Configure spotclean for error sanitization\nconfigureErrorSanitizer({\n enabled: true,\n environment: process.env.NODE_ENV === 'production' ? 'production' : 'development',\n includeCorrelationId: true,\n sanitizeStackTraces: process.env.NODE_ENV === 'production',\n maxMessageLength: 500,\n});\n\nconfigureSecretGuard({\n enabled: true,\n redactionText: '[REDACTED]',\n preservePartial: false,\n preserveLength: 0,\n customPatterns: [\n { name: 'gemini', pattern: /AIza[a-zA-Z0-9_-]{35}/g, description: 'Google Gemini API key' },\n ],\n});\n\n// ===== INLINE TYPES (from 'execution' package) =====\n\nexport type Model = string;\n\nexport interface Message {\n role: 'user' | 'assistant' | 'system' | 'developer' | 'tool';\n content: string | string[] | null;\n name?: string;\n}\n\nexport interface Request {\n messages: Message[];\n model: Model;\n responseFormat?: any;\n validator?: any;\n addMessage(message: Message): void;\n}\n\nexport interface ProviderResponse {\n content: string;\n model: string;\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n toolCalls?: Array<{\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }>;\n}\n\nexport interface ExecutionOptions {\n apiKey?: string;\n model?: string;\n temperature?: number;\n maxTokens?: number;\n timeout?: number;\n retries?: number;\n}\n\nexport interface Provider {\n readonly name: string;\n execute(request: Request, options?: ExecutionOptions): Promise<ProviderResponse>;\n supportsModel?(model: Model): boolean;\n}\n\n/**\n * Gemini Provider implementation\n */\nexport class GeminiProvider implements Provider {\n readonly name = 'gemini';\n\n /**\n * Check if this provider supports a given model\n */\n supportsModel(model: Model): boolean {\n if (!model) return false;\n return model.startsWith('gemini');\n }\n\n /**\n * Execute a request against Gemini\n */\n async execute(\n request: Request,\n options: ExecutionOptions = {}\n ): Promise<ProviderResponse> {\n const apiKey = options.apiKey || process.env.GEMINI_API_KEY;\n \n if (!apiKey) {\n throw new Error('Gemini API key is required. Set GEMINI_API_KEY environment variable.');\n }\n\n // Validate key format\n const validation = redactor.validateKey(apiKey, 'gemini');\n if (!validation.valid) {\n throw new Error('Invalid Gemini API key format');\n }\n\n try {\n const genAI = new GoogleGenerativeAI(apiKey);\n\n const modelName = options.model || request.model || 'gemini-1.5-pro';\n\n // Handle generation config for structured output\n const generationConfig: any = {};\n\n if (request.responseFormat?.type === 'json_schema') {\n generationConfig.responseMimeType = 'application/json';\n\n const openAISchema = request.responseFormat.json_schema.schema;\n\n // Map schema types to uppercase for Gemini\n const mapSchema = (s: any): any => {\n if (!s) return undefined;\n\n const newSchema: any = { ...s };\n\n if (newSchema.type) {\n newSchema.type =\n typeof newSchema.type === 'string'\n ? (newSchema.type as string).toUpperCase()\n : newSchema.type;\n }\n\n if (newSchema.properties) {\n const newProps: any = {};\n for (const [key, val] of Object.entries(newSchema.properties)) {\n newProps[key] = mapSchema(val);\n }\n newSchema.properties = newProps;\n }\n\n if (newSchema.items) {\n newSchema.items = mapSchema(newSchema.items);\n }\n\n delete newSchema.additionalProperties;\n delete newSchema['$schema'];\n\n return newSchema;\n };\n\n generationConfig.responseSchema = mapSchema(openAISchema);\n }\n\n // Extract system instruction\n let systemInstruction = '';\n\n for (const msg of request.messages) {\n if (msg.role === 'system' || msg.role === 'developer') {\n systemInstruction +=\n (typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content)) + '\\n\\n';\n }\n }\n\n const configuredModel = genAI.getGenerativeModel({\n model: modelName,\n systemInstruction: systemInstruction\n ? systemInstruction.trim()\n : undefined,\n generationConfig,\n });\n\n // Build history/messages\n const chatHistory = [];\n let lastUserMessage = '';\n\n for (const msg of request.messages) {\n if (msg.role === 'system' || msg.role === 'developer') continue;\n\n const content =\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content);\n\n if (msg.role === 'user') {\n lastUserMessage = content;\n }\n\n chatHistory.push({\n role: msg.role === 'assistant' ? 'model' : 'user',\n parts: [{ text: content }],\n });\n }\n\n let result;\n\n if (chatHistory.length > 1) {\n const lastMsg = chatHistory.pop();\n const chat = configuredModel.startChat({\n history: chatHistory,\n });\n result = await chat.sendMessage(lastMsg?.parts[0].text || '');\n } else {\n result = await configuredModel.generateContent(lastUserMessage || ' ');\n }\n\n const response = await result.response;\n const text = response.text();\n\n return {\n content: text,\n model: modelName,\n usage: response.usageMetadata\n ? {\n inputTokens: response.usageMetadata.promptTokenCount,\n outputTokens: response.usageMetadata.candidatesTokenCount,\n }\n : undefined,\n };\n } catch (error) {\n // Sanitize error to remove any API keys from error messages\n // Use spotclean for comprehensive error sanitization\n throw createSafeError(error as Error, { provider: 'gemini' });\n }\n }\n}\n\n/**\n * Create a new Gemini provider instance\n */\nexport function createGeminiProvider(): GeminiProvider {\n return new GeminiProvider();\n}\n\n/**\n * Package version\n */\nexport const VERSION = '0.0.1';\n\nexport default GeminiProvider;\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riotprompt/execution-gemini",
3
- "version": "0.0.4",
3
+ "version": "1.0.1-dev.0",
4
4
  "description": "Google Gemini provider for execution interface",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  "test": "vitest run --coverage",
21
21
  "test:coverage": "vitest run --coverage",
22
22
  "lint": "eslint src",
23
- "precommit": "npm run lint && npm run test",
23
+ "precommit": "npm run build && npm run lint && npm run test",
24
24
  "prepublishOnly": "npm run clean && npm run build"
25
25
  },
26
26
  "keywords": [
@@ -37,13 +37,16 @@
37
37
  "url": "https://github.com/kjerneverk/execution-gemini"
38
38
  },
39
39
  "dependencies": {
40
- "@google/generative-ai": "^0.24.0"
40
+ "@google/generative-ai": "^0.24.0",
41
+ "@theunwalked/offrecord": "^0.0.1",
42
+ "@theunwalked/spotclean": "^0.0.3"
41
43
  },
42
44
  "devDependencies": {
43
45
  "@types/node": "^25.0.6",
44
46
  "@typescript-eslint/eslint-plugin": "^8.33.1",
45
47
  "@typescript-eslint/parser": "^8.33.1",
46
48
  "@vitest/coverage-v8": "^3.2.4",
49
+ "ajv": "^8.17.1",
47
50
  "eslint": "^9.28.0",
48
51
  "globals": "^16.2.0",
49
52
  "typescript": "^5.8.3",