summaryrefslogtreecommitdiff
path: root/packages/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/server/src')
-rw-r--r--packages/server/src/core/client.ts50
-rw-r--r--packages/server/src/core/turn.ts14
2 files changed, 16 insertions, 48 deletions
diff --git a/packages/server/src/core/client.ts b/packages/server/src/core/client.ts
index 489e2a0b..85850da8 100644
--- a/packages/server/src/core/client.ts
+++ b/packages/server/src/core/client.ts
@@ -16,7 +16,7 @@ import {
} from '@google/genai';
import process from 'node:process';
import { getFolderStructure } from '../utils/getFolderStructure.js';
-import { Turn, ServerGeminiStreamEvent, GeminiEventType } from './turn.js';
+import { Turn, ServerGeminiStreamEvent } from './turn.js';
import { Config } from '../config/config.js';
import { getCoreSystemPrompt } from './prompts.js';
import { ReadManyFilesTool } from '../tools/read-many-files.js';
@@ -153,43 +153,23 @@ export class GeminiClient {
chat: Chat,
request: PartListUnion,
signal?: AbortSignal,
+ turns: number = this.MAX_TURNS,
): AsyncGenerator<ServerGeminiStreamEvent> {
- let turns = 0;
- while (turns < this.MAX_TURNS) {
- turns++;
- const turn = new Turn(chat);
- const resultStream = turn.run(request, signal);
- let seenError = false;
- for await (const event of resultStream) {
- seenError =
- seenError === false ? false : event.type === GeminiEventType.Error;
- yield event;
- }
-
- const confirmations = turn.getConfirmationDetails();
- if (confirmations.length > 0) {
- break;
- }
-
- const fnResponses = turn.getFunctionResponses();
- if (fnResponses.length === 0) {
- const nextSpeakerCheck = await checkNextSpeaker(chat, this);
- if (nextSpeakerCheck?.next_speaker === 'model') {
- request = [{ text: 'Please continue.' }];
- continue;
- } else {
- break;
- }
- }
- request = fnResponses;
+ if (!turns) {
+ return;
+ }
- if (seenError) {
- // We saw an error, lets stop processing to prevent unexpected consequences.
- break;
- }
+ const turn = new Turn(chat);
+ const resultStream = turn.run(request, signal);
+ for await (const event of resultStream) {
+ yield event;
}
- if (turns >= this.MAX_TURNS) {
- console.warn('sendMessageStream: Reached maximum tool call turns limit.');
+ if (!turn.pendingToolCalls.length) {
+ const nextSpeakerCheck = await checkNextSpeaker(chat, this);
+ if (nextSpeakerCheck?.next_speaker === 'model') {
+ const nextRequest = [{ text: 'Please continue.' }];
+ return this.sendMessageStream(chat, nextRequest, signal, turns - 1);
+ }
}
}
diff --git a/packages/server/src/core/turn.ts b/packages/server/src/core/turn.ts
index 7b2a96f9..38932041 100644
--- a/packages/server/src/core/turn.ts
+++ b/packages/server/src/core/turn.ts
@@ -106,19 +106,15 @@ export type ServerGeminiStreamEvent =
// A turn manages the agentic loop turn within the server context.
export class Turn {
- private pendingToolCalls: Array<{
+ readonly pendingToolCalls: Array<{
callId: string;
name: string;
args: Record<string, unknown>;
}>;
- private fnResponses: Part[];
- private confirmationDetails: ToolCallConfirmationDetails[];
private debugResponses: GenerateContentResponse[];
constructor(private readonly chat: Chat) {
this.pendingToolCalls = [];
- this.fnResponses = [];
- this.confirmationDetails = [];
this.debugResponses = [];
}
// The run method yields simpler events suitable for server logic
@@ -182,14 +178,6 @@ export class Turn {
return { type: GeminiEventType.ToolCallRequest, value };
}
- getConfirmationDetails(): ToolCallConfirmationDetails[] {
- return this.confirmationDetails;
- }
-
- getFunctionResponses(): Part[] {
- return this.fnResponses;
- }
-
getDebugResponses(): GenerateContentResponse[] {
return this.debugResponses;
}