File size: 4,103 Bytes
3801376
 
 
9968058
 
8980628
3801376
 
 
8980628
 
 
 
 
 
 
3801376
 
 
8980628
 
 
 
3801376
 
 
 
 
 
 
8980628
 
 
3801376
 
 
 
9968058
3801376
 
 
 
9968058
8980628
 
 
 
 
 
 
 
 
 
 
 
9968058
8980628
 
 
 
 
 
 
 
 
 
 
3801376
 
 
 
 
 
 
8980628
 
3801376
 
9968058
3801376
 
9968058
 
3801376
 
9968058
8980628
3801376
 
 
 
 
 
 
 
 
8980628
 
 
 
 
3801376
 
 
 
 
8980628
 
 
 
 
 
 
9968058
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Default system prompt used if none is provided
const DEFAULT_SYSTEM_PROMPT = 'You are a helpful and honest assistant. Please, respond concisely and truthfully.';

// Base model for Hugging Face API
const DEFAULT_MODEL = "mistralai/Mistral-7B-Instruct-v0.3";

/**
 * Adds a custom menu to Google Sheets to allow users to input their Hugging Face API key.
 */
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('Hugging Sheets')
    .addItem('Enter your HF API Key', 'showApiKeyPrompt')
    .addToUi();
}

/**
 * Prompts the user to enter their Hugging Face API key and saves it in the script properties.
 */
function showApiKeyPrompt() {
  const ui = SpreadsheetApp.getUi();
  const response = ui.prompt('Enter your Hugging Face API Key:');
  if (response.getSelectedButton() == ui.Button.OK) {
    const apiKey = response.getResponseText().trim();
    if (apiKey) {
      PropertiesService.getScriptProperties().setProperty('HF_API_KEY', apiKey);
      ui.alert('API Key saved successfully!');
    } else {
      ui.alert('API Key cannot be empty.');
    }
  }
}

/**
 * Sends a request to the Hugging Face API with the specified prompt and model.
 * 
 * @param {string} prompt - The input prompt to be sent to the model.
 * @param {string} [model=DEFAULT_MODEL] - The model ID to query (e.g., 'mistralai/Mistral-7B-Instruct-v0.3').
 * @param {string} [systemPrompt=DEFAULT_SYSTEM_PROMPT] - The system prompt to customize the assistant's behavior.
 * @returns {object} JSON response from the Hugging Face API.
 * @throws {Error} If the API key is not set or if the API request fails.
 */
function queryHuggingFace(prompt, model = DEFAULT_MODEL, systemPrompt = DEFAULT_SYSTEM_PROMPT) {
  const apiKey = PropertiesService.getScriptProperties().getProperty('HF_API_KEY');
  if (!apiKey) {
    throw new Error('Please enter your Hugging Face API key using the menu.');
  }

  const url = `https://api-inference.huggingface.co/models/${model}`;
  const headers = {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json"
  };


  const formattedPrompt = `<s> [INST] ${systemPrompt} [/INST] ${prompt} </s>`;
  const payload = {
    "inputs": formattedPrompt
  };


  const options = {
    "method": "post",
    "headers": headers,
    "payload": JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    const json = JSON.parse(response.getContentText());
    return json;
  } catch (error) {
    throw new Error(`Failed to fetch data from Hugging Face API: ${error.message}`);
  }
}

/**
 * Custom Google Sheets formula to query the Hugging Face API and return the generated text.
 * Function to create the custom formula =HF(prompt; [model]; [systemPrompt])
 * 
 * @param {string} prompt - The input prompt to be sent to the model.
 * @param {string} [model=DEFAULT_MODEL] - The model ID to query (e.g., 'mistralai/Mistral-7B-Instruct-v0.3').
 * @param {string} [systemPrompt=DEFAULT_SYSTEM_PROMPT] - The system prompt to customize the assistant's behavior. Defaults to DEFAULT_SYSTEM_PROMPT.
 * @returns {string} The generated output text from the Hugging Face API, or an error message if the request fails.
 */
function HF(prompt, model = DEFAULT_MODEL, systemPrompt = DEFAULT_SYSTEM_PROMPT) {
  try {
    const response = queryHuggingFace(prompt, model, systemPrompt);
    if (response && response.length > 0 && response[0].generated_text) {
      const fullResponse = response[0].generated_text;
      // Extract the part of the response after the prompt
      const generatedOutput = fullResponse.split(`</s>`).pop().trim();
      return generatedOutput;
    } else {
      return 'Error: Invalid response structure from Hugging Face API.';
    }
  } catch (error) {
    return `Error: ${error.message}`;
  }
}

/**
 * Add the formula to Google Sheets.
 * 
 * @param {object} e - The event object.
 */
function onInstall(e) {
  onOpen(e);
  const formula = SpreadsheetApp.newUserDefinedFunctionBuilder()
    .setName('HF')
    .setFunction('HF')
    .build();
  SpreadsheetApp.installUserDefinedFunction(formula);
}