mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-19 16:55:02 +02:00
fix, wip
This commit is contained in:
parent
47c312f7d3
commit
6eb7b75296
|
|
@ -17,7 +17,7 @@ import type {
|
|||
Tool,
|
||||
GenerateContentGenerationConfig,
|
||||
} from '../../helpers/interfaces';
|
||||
import { apiRequest } from '../../transport';
|
||||
import { streamingRequestWithFallback } from '../../transport';
|
||||
import { modelRLC } from '../descriptions';
|
||||
|
||||
const properties: INodeProperties[] = [
|
||||
|
|
@ -319,9 +319,7 @@ export async function execute(this: IExecuteFunctions, i: number): Promise<INode
|
|||
: undefined,
|
||||
};
|
||||
|
||||
let response = (await apiRequest.call(this, 'POST', `/v1beta/${model}:generateContent`, {
|
||||
body,
|
||||
})) as GenerateContentResponse;
|
||||
let response = await streamingRequestWithFallback.call(this, model, body);
|
||||
|
||||
const maxToolsIterations = this.getNodeParameter('options.maxToolsIterations', i, 15) as number;
|
||||
const abortSignal = this.getExecutionCancelSignal();
|
||||
|
|
@ -361,9 +359,7 @@ export async function execute(this: IExecuteFunctions, i: number): Promise<INode
|
|||
});
|
||||
}
|
||||
|
||||
response = (await apiRequest.call(this, 'POST', `/v1beta/${model}:generateContent`, {
|
||||
body,
|
||||
})) as GenerateContentResponse;
|
||||
response = await streamingRequestWithFallback.call(this, model, body);
|
||||
toolCalls = getToolCalls(response);
|
||||
currentIteration++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import type {
|
|||
IHttpRequestMethods,
|
||||
ILoadOptionsFunctions,
|
||||
} from 'n8n-workflow';
|
||||
import { NodeOperationError } from 'n8n-workflow';
|
||||
import type { GenerateContentRequest, GenerateContentResponse } from '../helpers/interfaces';
|
||||
|
||||
type RequestParameters = {
|
||||
headers?: IDataObject;
|
||||
|
|
@ -48,3 +50,106 @@ export async function apiRequest(
|
|||
|
||||
return await this.helpers.httpRequestWithAuthentication.call(this, 'googlePalmApi', options);
|
||||
}
|
||||
async function apiRequestStream(
|
||||
this: IExecuteFunctions | ILoadOptionsFunctions,
|
||||
method: IHttpRequestMethods,
|
||||
endpoint: string,
|
||||
parameters?: RequestParameters,
|
||||
): Promise<any> {
|
||||
const { body, qs, option, headers } = parameters ?? {};
|
||||
|
||||
const credentials = await this.getCredentials<GooglePalmApiCredentials>('googlePalmApi');
|
||||
|
||||
let url = `https://generativelanguage.googleapis.com${endpoint}`;
|
||||
|
||||
if (credentials.host) {
|
||||
url = `${credentials.host}${endpoint}`;
|
||||
}
|
||||
|
||||
const streamingQs = { ...qs, alt: 'sse' };
|
||||
|
||||
const options = {
|
||||
headers: {
|
||||
...headers,
|
||||
Accept: 'text/event-stream',
|
||||
},
|
||||
method,
|
||||
body,
|
||||
qs: streamingQs,
|
||||
url,
|
||||
json: false,
|
||||
};
|
||||
|
||||
if (option && Object.keys(option).length !== 0) {
|
||||
Object.assign(options, option);
|
||||
}
|
||||
|
||||
const response = await this.helpers.httpRequestWithAuthentication.call(
|
||||
this,
|
||||
'googlePalmApi',
|
||||
options,
|
||||
);
|
||||
|
||||
return parseStreamingResponse(response);
|
||||
}
|
||||
|
||||
function parseStreamingResponse(streamData: string): any {
|
||||
const lines = streamData.split('\n');
|
||||
const chunks = [];
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const data = line.slice(6);
|
||||
if (data === '[DONE]') {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(data);
|
||||
chunks.push(parsed);
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chunks.length === 0) {
|
||||
throw new NodeOperationError(
|
||||
null as any,
|
||||
'No valid response chunks received from streaming API',
|
||||
);
|
||||
}
|
||||
|
||||
const combinedResponse = {
|
||||
candidates: [
|
||||
{
|
||||
content: {
|
||||
parts: [
|
||||
{
|
||||
//TODO: combine other fields
|
||||
text: chunks
|
||||
.filter((chunk) => chunk.candidates?.[0]?.content?.parts?.[0]?.text)
|
||||
.map((chunk) => chunk.candidates[0].content.parts[0].text)
|
||||
.join(''),
|
||||
},
|
||||
],
|
||||
role: 'model',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
return combinedResponse;
|
||||
}
|
||||
|
||||
export async function streamingRequestWithFallback(
|
||||
this: IExecuteFunctions,
|
||||
model: string,
|
||||
body: GenerateContentRequest,
|
||||
) {
|
||||
try {
|
||||
return (await apiRequestStream.call(this, 'POST', `/v1beta/${model}:streamGenerateContent`, {
|
||||
body,
|
||||
})) as GenerateContentResponse;
|
||||
} catch (streamError: any) {
|
||||
return (await apiRequest.call(this, 'POST', `/v1beta/${model}:generateContent`, {
|
||||
body,
|
||||
})) as GenerateContentResponse;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user