You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: req.go
    path of file: ./repos/erda/internal/apps/ai-proxy/filters/audit-before-llm-director
    
    the code of the file until where you have to start completion: // Copyright (c) 2021 Terminus, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package audit_before_llm_director

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/sashabaranov/go-openai"
	"google.golang.org/protobuf/types/known/timestamppb"

	"github.com/erda-project/erda-infra/providers/component-protocol/utils/cputil"
	"github.com/erda-project/erda-proto-go/apps/aiproxy/audit/pb"
	modelpb "github.com/erda-project/erda-proto-go/apps/aiproxy/model/pb"
	"github.com/erda-project/erda/internal/apps/ai-proxy/common/ctxhelper"
	"github.com/erda-project/erda/internal/apps/ai-proxy/vars"
	"github.com/erda-project/erda/pkg/http
    
func (f *Filter) OnRequestBeforeLLMDirector(ctx context.Context, w http.ResponseWriter, infor reverseproxy.HttpInfor) (signal reverseproxy.Signal, err error) {
	auditRecID, ok := ctxhelper.GetAuditID(ctx)
	if !ok || auditRecID == "" {
		return
	}

	var updateReq pb.AuditUpdateRequestAfterSpecificContextParsed
	updateReq.AuditId = auditRecID
	// prompt
	prompt, _ := ctxhelper.GetUserPrompt(ctx)
	updateReq.Prompt = prompt

	// metadata, routing by model type
	model, _ := ctxhelper.GetModel(ctx)
	switch model.Type {
	case modelpb.ModelType_text_generation:
		var openaiReq openai.ChatCompletionRequest
		if err := json.NewDecoder(infor.BodyBuffer()).Decode(&openaiReq); err != nil {
			goto Next
		}
		updateReq.RequestFunctionCallName = func() string {
			// switch type
			switch openaiReq.FunctionCall.(type) {
			case string:
				return openaiReq.FunctionCall.(string)
			case map[string]interface{}:
				var reqFuncCall openai.FunctionCall
				cputil.MustObjJSONTransfer(openaiReq.FunctionCall, &reqFuncCall)
				return reqFuncCall.Name
			case openai.FunctionCall:
				return openaiReq.FunctionCall.(openai.FunctionCall).Name
			case nil:
				return ""
			default:
				return fmt.Sprintf("%v", openaiReq.FunctionCall)
			}
		}()
	case modelpb.ModelType_audio:
		audioInfo, ok := ctxhelper.GetAudioInfo(ctx)
		if !ok {
			goto Next
		}
		updateReq.AudioFileName = audioInfo.FileName
		updateReq.AudioFileSize = audioInfo.FileSize.String()
		updateReq.AudioFileHeaders = func() string {
			b, err := json.Marshal(audioInfo.FileHeaders)
			if err != nil {
				return err.Error()
			}
			return string(b)
		}()
	case modelpb.ModelType_image:
		imageInfo, ok := ctxhelper.GetImageInfo(ctx)
		if !ok {
			goto Next
		}
		updateReq.ImageQuality = imageInfo.ImageQuality
		updateReq.ImageSize = imageInfo.ImageSize
		updateReq.ImageStyle = imageInfo.ImageStyle
	default:
		// do nothing
	}

Next:

	// update audit into db
	_, err = ctxhelper.MustGetDBClient(ctx).AuditClient().UpdateAfterSpecificContextParsed(ctx, &updateReq)
	if err != nil {
		// log it
		l := ctxhelper.GetLogger(ctx)
		l.Errorf("failed to update audit: %v", err)
	}
	return reverseproxy.Continue, nil
}