mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-23 15:08:12 +02:00
feat: implement admin AI chat API with SQL execution and schema retrieval tools
This commit is contained in:
1 parent
4994d55ffc
commit
0c1d3c10bd
1 file changed
+32
-27
@@ -253,48 +253,54 @@ async function handleGoogleAi(messages: Array<{ role: string; content: string }>
|
|||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Agentic loop — non-streaming tool phase, streaming final answer
|
// Agentic loop — streaming throughout
|
||||||
for (let round = 0; round < 8; round++) {
|
for (let round = 0; round < 8; round++) {
|
||||||
const response = await ai.models.generateContent({
|
const streamResponse = await ai.models.generateContentStream({
|
||||||
model,
|
model,
|
||||||
contents: contents as any,
|
contents: contents as any,
|
||||||
config: {
|
config: {
|
||||||
systemInstruction: SYSTEM_PROMPT,
|
systemInstruction: SYSTEM_PROMPT,
|
||||||
tools: googleTools as any,
|
tools: googleTools as any,
|
||||||
|
maxOutputTokens: 8192,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const fnCalls = response.functionCalls;
|
// Collect stream, forwarding text chunks immediately
|
||||||
|
let collectedText = "";
|
||||||
|
const collectedParts: any[] = [];
|
||||||
|
|
||||||
if (!fnCalls || fnCalls.length === 0) {
|
for await (const chunk of streamResponse) {
|
||||||
// No tool calls — stream the final text
|
const text = chunk.text;
|
||||||
const streamResponse = await ai.models.generateContentStream({
|
if (text) {
|
||||||
model,
|
collectedText += text;
|
||||||
contents: contents as any,
|
send({ type: "text", content: text });
|
||||||
config: {
|
|
||||||
systemInstruction: SYSTEM_PROMPT,
|
|
||||||
tools: googleTools as any,
|
|
||||||
maxOutputTokens: 8192,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
for await (const chunk of streamResponse) {
|
|
||||||
const text = chunk.text;
|
|
||||||
if (text) send({ type: "text", content: text });
|
|
||||||
}
|
}
|
||||||
|
// Collect parts for function calls
|
||||||
|
const parts = chunk.candidates?.[0]?.content?.parts;
|
||||||
|
if (parts) collectedParts.push(...parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for function calls in collected parts
|
||||||
|
const fnCallParts = collectedParts.filter((p: any) => p.functionCall);
|
||||||
|
|
||||||
|
if (fnCallParts.length === 0) {
|
||||||
|
// Pure text response — done
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add model response with function calls to history
|
// Had function calls — add model turn to history
|
||||||
contents.push({
|
if (collectedText) {
|
||||||
role: "model",
|
// Mixed text + function calls
|
||||||
parts: response.candidates![0].content!.parts as any,
|
contents.push({ role: "model", parts: collectedParts });
|
||||||
});
|
} else {
|
||||||
|
contents.push({ role: "model", parts: fnCallParts });
|
||||||
|
}
|
||||||
|
|
||||||
// Execute tool calls
|
// Execute tool calls
|
||||||
const toolResultParts: Array<{ functionResponse: { name: string; response: { output: string } } }> = [];
|
const toolResultParts: Array<{ functionResponse: { name: string; response: { output: string } } }> = [];
|
||||||
for (const fn of fnCalls) {
|
for (const part of fnCallParts) {
|
||||||
const args = (fn.args ?? {}) as Record<string, unknown>;
|
const fn = part.functionCall as { name: string; args: Record<string, unknown> };
|
||||||
|
const args = fn.args ?? {};
|
||||||
send({ type: "tool_start", name: fn.name, args });
|
send({ type: "tool_start", name: fn.name, args });
|
||||||
|
|
||||||
let result = "";
|
let result = "";
|
||||||
@@ -307,10 +313,9 @@ async function handleGoogleAi(messages: Array<{ role: string; content: string }>
|
|||||||
}
|
}
|
||||||
|
|
||||||
send({ type: "tool_result", name: fn.name, result: result.substring(0, 500) + (result.length > 500 ? "..." : "") });
|
send({ type: "tool_result", name: fn.name, result: result.substring(0, 500) + (result.length > 500 ? "..." : "") });
|
||||||
toolResultParts.push({ functionResponse: { name: fn.name!, response: { output: result } } });
|
toolResultParts.push({ functionResponse: { name: fn.name, response: { output: result } } });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add tool results to history
|
|
||||||
contents.push({ role: "user", parts: toolResultParts as any });
|
contents.push({ role: "user", parts: toolResultParts as any });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user