MCPcopy Create free account
hub / github.com/coder/aibridge / ProcessRequest

Method ProcessRequest

intercept/messages/blocking.go:69–336  ·  view source on GitHub ↗
(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

67}
68
69func (i *BlockingInterception) ProcessRequest(w http.ResponseWriter, r *http.Request) (outErr error) {
70 if len(i.reqPayload) == 0 {
71 return xerrors.New("developer error: request payload is empty")
72 }
73
74 ctx, span := i.tracer.Start(r.Context(), "Intercept.ProcessRequest", trace.WithAttributes(tracing.InterceptionAttributesFromContext(r.Context())...))
75 defer tracing.EndSpanErr(span, &outErr)
76
77 i.injectTools()
78
79 var prompt *string
80 promptText, promptFound, promptErr := i.reqPayload.lastUserPrompt()
81 if promptErr != nil {
82 i.logger.Warn(ctx, "failed to retrieve last user prompt", slog.Error(promptErr))
83 } else if promptFound {
84 prompt = &promptText
85 }
86
87 // TODO(ssncferreira): inject actor headers directly in the client-header
88 // middleware instead of using SDK options.
89 opts := []option.RequestOption{option.WithRequestTimeout(time.Second * 600)}
90 if actor := aibcontext.ActorFromContext(r.Context()); actor != nil && i.cfg.SendActorHeaders {
91 opts = append(opts, intercept.ActorHeadersAsAnthropicOpts(actor)...)
92 }
93
94 svc, err := i.newMessagesService(ctx, opts...)
95 if err != nil {
96 err = xerrors.Errorf("create anthropic client: %w", err)
97 http.Error(w, err.Error(), http.StatusInternalServerError)
98 return err
99 }
100
101 logger := i.logger.With(slog.F("model", i.Model()))
102
103 var resp *anthropic.Message
104 // Accumulate usage across the entire streaming interaction (including tool reinvocations).
105 var cumulativeUsage anthropic.Usage
106
107 for {
108 // TODO add outer loop span (https://github.com/coder/aibridge/issues/67)
109 resp, err = i.newMessage(ctx, svc)
110 if err != nil {
111 if eventstream.IsConnError(err) {
112 // Can't write a response, just error out.
113 return xerrors.Errorf("upstream connection closed: %w", err)
114 }
115
116 if antErr := getErrorResponse(err); antErr != nil {
117 i.writeUpstreamError(w, antErr)
118 return xerrors.Errorf("anthropic API error: %w", err)
119 }
120
121 http.Error(w, "internal error", http.StatusInternalServerError)
122 return xerrors.Errorf("internal error: %w", err)
123 }
124
125 if prompt != nil {
126 _ = i.recorder.RecordPromptUsage(ctx, &recorder.PromptUsageRecord{

Callers

nothing calls this directly

Calls 15

newMessageMethod · 0.95
EndSpanErrFunction · 0.92
IsConnErrorFunction · 0.92
accumulateUsageFunction · 0.85
StartMethod · 0.80
newMessagesServiceMethod · 0.80
CallMethod · 0.80
appendedMessagesMethod · 0.80
HeaderMethod · 0.80
getErrorResponseFunction · 0.70

Tested by

no test coverage detected