| 908 | } |
| 909 | |
| 910 | async *sendMessageStream( |
| 911 | request: PartListUnion, |
| 912 | signal: AbortSignal, |
| 913 | prompt_id: string, |
| 914 | turns: number = MAX_TURNS, |
| 915 | displayContent?: PartListUnion, |
| 916 | stopHookActive: boolean = false, |
| 917 | ): AsyncGenerator<ServerGeminiStreamEvent, Turn> { |
| 918 | this.config.resetTurn(); |
| 919 | |
| 920 | const hooksEnabled = this.config.getEnableHooks(); |
| 921 | const messageBus = this.context.messageBus; |
| 922 | |
| 923 | if (this.lastPromptId !== prompt_id) { |
| 924 | this.loopDetector.reset(prompt_id, partListUnionToString(request)); |
| 925 | this.hookStateMap.delete(this.lastPromptId); |
| 926 | this.lastPromptId = prompt_id; |
| 927 | this.currentSequenceModel = null; |
| 928 | } |
| 929 | |
| 930 | if (hooksEnabled && messageBus) { |
| 931 | const hookResult = await this.fireBeforeAgentHookSafe(request, prompt_id); |
| 932 | if (hookResult) { |
| 933 | if ( |
| 934 | 'type' in hookResult && |
| 935 | hookResult.type === GeminiEventType.AgentExecutionStopped |
| 936 | ) { |
| 937 | // Add user message to history before returning so it's kept in the transcript |
| 938 | this.getChat().addHistory(createUserContent(request)); |
| 939 | yield hookResult; |
| 940 | return new Turn(this.getChat(), prompt_id); |
| 941 | } else if ( |
| 942 | 'type' in hookResult && |
| 943 | hookResult.type === GeminiEventType.AgentExecutionBlocked |
| 944 | ) { |
| 945 | yield hookResult; |
| 946 | return new Turn(this.getChat(), prompt_id); |
| 947 | } else if ('additionalContext' in hookResult) { |
| 948 | const additionalContext = hookResult.additionalContext; |
| 949 | if (additionalContext) { |
| 950 | const requestArray = Array.isArray(request) ? request : [request]; |
| 951 | request = [ |
| 952 | ...requestArray, |
| 953 | { text: `<hook_context>${additionalContext}</hook_context>` }, |
| 954 | ]; |
| 955 | } |
| 956 | } |
| 957 | } |
| 958 | } |
| 959 | |
| 960 | const boundedTurns = Math.min(turns, MAX_TURNS); |
| 961 | let turn = new Turn(this.getChat(), prompt_id); |
| 962 | let continuationHandled = false; |
| 963 | |
| 964 | try { |
| 965 | turn = yield* this.processTurn( |
| 966 | request, |
| 967 | signal, |