n8n-nodes-handit
Version:
n8n community nodes for Handit tracing and prompt management
252 lines • 11.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.HanditPromptFetcher = void 0;
const n8n_workflow_1 = require("n8n-workflow");
class HanditPromptFetcher {
constructor() {
this.description = {
displayName: 'Handit Prompt Fetcher',
name: 'handitPromptFetcher',
icon: 'file:handit.svg',
group: ['input'],
version: 1,
description: 'Fetch production prompts from Handit API and make them available as variables for LLM nodes',
defaults: {
name: 'Handit Prompt Fetcher',
},
inputs: ["main"],
outputs: ["main"],
credentials: [
{
name: 'handitApi',
required: true,
},
],
properties: [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
options: [
{
name: 'Fetch Prompts',
value: 'fetchPrompts',
description: 'Fetch production prompts for an agent',
action: 'Fetch production prompts',
},
],
default: 'fetchPrompts',
noDataExpression: true,
},
{
displayName: 'Agent Name/Slug',
name: 'agentSlug',
type: 'string',
default: '',
required: true,
placeholder: 'my-agent-slug',
description: 'The name or slug of the agent to fetch prompts for',
displayOptions: {
show: {
operation: ['fetchPrompts'],
},
},
},
{
displayName: 'Output Format',
name: 'outputFormat',
type: 'options',
options: [
{
name: 'Individual Variables',
value: 'variables',
description: 'Create individual variables for each LLM node (e.g., $gpt4_prompt, $claude_prompt)',
},
{
name: 'JSON Object',
value: 'json',
description: 'Return all prompts as a single JSON object',
},
{
name: 'Both',
value: 'both',
description: 'Create both individual variables and a JSON object',
},
],
default: 'variables',
description: 'How to format the output prompts',
displayOptions: {
show: {
operation: ['fetchPrompts'],
},
},
},
{
displayName: 'Variable Prefix',
name: 'variablePrefix',
type: 'string',
default: '',
placeholder: 'prompt_',
description: 'Optional prefix for variable names (e.g., "prompt_" creates $prompt_gpt4, $prompt_claude)',
displayOptions: {
show: {
operation: ['fetchPrompts'],
outputFormat: ['variables', 'both'],
},
},
},
{
displayName: 'Additional Options',
name: 'additionalOptions',
type: 'collection',
placeholder: 'Add Option',
default: {},
displayOptions: {
show: {
operation: ['fetchPrompts'],
},
},
options: [
{
displayName: 'Environment',
name: 'environment',
type: 'options',
options: [
{
name: 'Production',
value: 'production',
},
{
name: 'Staging',
value: 'staging',
},
{
name: 'Development',
value: 'development',
},
],
default: 'production',
description: 'Environment to fetch prompts from',
},
{
displayName: 'Version',
name: 'version',
type: 'string',
default: 'latest',
description: 'Specific version of prompts to fetch (default: latest)',
},
{
displayName: 'Cache Duration (Minutes)',
name: 'cacheDuration',
type: 'number',
default: 5,
description: 'How long to cache prompts to avoid repeated API calls',
},
],
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
const operation = this.getNodeParameter('operation', 0);
if (operation === 'fetchPrompts') {
for (let i = 0; i < items.length; i++) {
try {
const agentSlug = this.getNodeParameter('agentSlug', i);
const outputFormat = this.getNodeParameter('outputFormat', i);
const variablePrefix = this.getNodeParameter('variablePrefix', i);
const additionalOptions = this.getNodeParameter('additionalOptions', i);
const apiEndpoint = 'https://handit-api-oss-299768392189.us-central1.run.app/api/performance';
let requestUrl = apiEndpoint;
const queryParams = [];
queryParams.push(`agent=${encodeURIComponent(agentSlug)}`);
if (additionalOptions.environment) {
queryParams.push(`environment=${encodeURIComponent(additionalOptions.environment)}`);
}
if (additionalOptions.version) {
queryParams.push(`version=${encodeURIComponent(additionalOptions.version)}`);
}
if (queryParams.length > 0) {
requestUrl += (apiEndpoint.includes('?') ? '&' : '?') + queryParams.join('&');
}
const requestOptions = {
method: 'GET',
url: requestUrl,
json: true,
headers: {
'Content-Type': 'application/json',
},
};
const response = await this.helpers.requestWithAuthentication.call(this, 'handitApi', requestOptions);
let outputData = {
...items[i].json,
agentSlug,
fetchedAt: new Date().toISOString(),
};
if (!response || typeof response !== 'object') {
throw new n8n_workflow_1.NodeApiError(this.getNode(), response, {
message: 'Invalid response from API: expected JSON object',
});
}
const prompts = response.prompts || response;
if (outputFormat === 'json' || outputFormat === 'both') {
outputData.prompts = prompts;
outputData.promptsJson = JSON.stringify(prompts, null, 2);
}
if (outputFormat === 'variables' || outputFormat === 'both') {
if (typeof prompts === 'object' && prompts !== null) {
for (const [llmNode, prompt] of Object.entries(prompts)) {
const cleanNodeName = llmNode.toLowerCase()
.replace(/[^a-z0-9]/g, '_')
.replace(/_+/g, '_')
.replace(/^_|_$/g, '');
const variableName = variablePrefix
? `${variablePrefix}${cleanNodeName}`
: cleanNodeName;
outputData[variableName] = prompt;
outputData[`${variableName}_prompt`] = prompt;
}
}
}
outputData.promptMetadata = {
agentSlug,
environment: additionalOptions.environment || 'production',
version: additionalOptions.version || 'latest',
fetchedAt: outputData.fetchedAt,
totalPrompts: typeof prompts === 'object' ? Object.keys(prompts).length : 0,
availableNodes: typeof prompts === 'object' ? Object.keys(prompts) : [],
};
outputData.success = true;
const metadata = outputData.promptMetadata;
outputData.message = `Successfully fetched ${metadata.totalPrompts} prompts for agent "${agentSlug}"`;
returnData.push({
json: outputData,
pairedItem: {
item: i,
},
});
}
catch (error) {
const errorData = {
...items[i].json,
success: false,
error: error.message,
timestamp: new Date().toISOString(),
agentSlug: this.getNodeParameter('agentSlug', i),
};
returnData.push({
json: errorData,
pairedItem: {
item: i,
},
});
}
}
}
return [returnData];
}
}
exports.HanditPromptFetcher = HanditPromptFetcher;
//# sourceMappingURL=HanditPromptFetcher.node.js.map