// Client sends model calls to a Responses endpoint for one agent. The ChatGPT
// backend and the OpenAI API take the same request body and differ only in the
// URL and the credentials. Every call sends the fixed cache key of the agent,
-// so the turns and the compactions of the agent share one prompt cache. Every
-// call is recorded in the usage file.
+// so the turns and the compactions of the agent share one prompt cache. The
+// ChatGPT backend caches only with the key in the session_id header, so a call
+// to it sends the key there and in the body. Every call is recorded in the
+// usage file.
//
// The request never holds max_output_tokens or metadata, because the ChatGPT
// backend refuses them. It sets store to false, so the client sends the whole
return Response{}, fmt.Errorf("authorize model call: %w", err)
}
+ _, chatgpt := c.auth.(*chatgptAuth)
+ if chatgpt {
+ httpRequest.Header.Set("session_id", c.cacheKey)
+ }
+
record := usageRecord{
Date: time.Now().Format(time.RFC3339Nano),
Model: request.Model,
"path/filepath"
"sync"
"testing"
+ "time"
"github.com/stretchr/testify/require"
)
require.Len(t, body["tools"], 1)
}
+func TestClientSendsTheSessionHeaderToChatGPT(t *testing.T) {
+ login := newFakeAuth(t)
+ auth := newTestAuth(t, login)
+ writeTestTokens(t, auth, login.token(time.Hour), "refresh-0")
+
+ testCases := []struct {
+ name string
+ auth authorizer
+ want string
+ }{
+ {
+ name: "ChatGPT backend",
+ auth: auth,
+ want: "agent-key",
+ },
+ {
+ name: "OpenAI API",
+ auth: apiKey(testKey),
+ want: "",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ server := newFakeResponses(t)
+ client := newClient(server.URL, tc.auth, "agent-key", filepath.Join(t.TempDir(), "usage.jsonl"))
+ _, err := client.Create(t.Context(), testRequest())
+ require.NoError(t, err)
+
+ call := server.Call(0)
+ require.Equal(t, tc.want, call.header.Get("session_id"))
+ require.Equal(t, "agent-key", call.body["prompt_cache_key"])
+ })
+ }
+}
+
func TestClientReadsTheStream(t *testing.T) {
server := newFakeResponses(t)
server.reply = func(w http.ResponseWriter, call fakeCall) {