-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed BingChat to recent API changes. #41
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,4 +6,5 @@ riderModule.iml | |
.idea/ | ||
.DS_Store | ||
build/ | ||
publish/ | ||
publish/ | ||
.vs/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
using System.Net; | ||
using System.Net.Http.Json; | ||
using System.Runtime.CompilerServices; | ||
using System.Text.Json; | ||
using System.Text.Json.Nodes; | ||
using System.Web; | ||
|
||
|
@@ -41,6 +42,7 @@ public async Task<BingChatConversation> CreateConversation() | |
{ | ||
JsonNode? cookieJson = JsonNode.Parse(File.ReadAllText(_options.CookieFilePath)); | ||
cookies = new CookieContainer(); | ||
cookies.PerDomainCapacity = 100; | ||
foreach (var cookieItemJson in (JsonArray)cookieJson!) | ||
{ | ||
if (cookieItemJson is null) | ||
|
@@ -54,8 +56,14 @@ public async Task<BingChatConversation> CreateConversation() | |
string.IsNullOrEmpty(name) || | ||
string.IsNullOrEmpty(value)) | ||
continue; | ||
cookies.Add(new Uri("https://www.bing.com"), | ||
new Cookie(name, HttpUtility.UrlEncode(value), path, domain)); | ||
try | ||
{ | ||
cookies.Add(new Cookie(name, value, path, domain)); | ||
} | ||
catch | ||
{ | ||
cookies.Add(new Cookie(name, HttpUtility.UrlEncode(value), path, domain)); | ||
} | ||
} | ||
} | ||
catch | ||
|
@@ -88,14 +96,14 @@ public async Task<BingChatConversation> CreateConversation() | |
headers.Add("sec-fetch-site", "same-origin"); | ||
headers.Add("x-edge-shopping-flag", "1"); | ||
headers.Add("x-ms-client-request-id", requestId.ToString().ToLower()); | ||
headers.Add("x-ms-useragent", "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/MacIntel"); | ||
headers.Add("x-ms-useragent", "azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.12.0 OS/Windows"); | ||
headers.Add("referer", "https://www.bing.com/search"); | ||
headers.Add("referer-policy", "origin-when-cross-origin"); | ||
|
||
var response = await client.GetFromJsonAsync( | ||
"https://www.bing.com/turing/conversation/create", | ||
SerializerContext.Default.BingCreateConversationResponse); | ||
var rawResponse = await client.GetAsync("https://www.bing.com/turing/conversation/create?bundleVersion=1.1135.1"); | ||
|
||
var response = (BingCreateConversationResponse?)await rawResponse.Content.ReadFromJsonAsync(typeof(BingCreateConversationResponse),SerializerContext.Default); | ||
|
||
if (response!.Result is { } errResult && | ||
!errResult.Value.Equals("Success", StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
|
@@ -107,11 +115,15 @@ public async Task<BingChatConversation> CreateConversation() | |
throw new BingChatException(message); | ||
} | ||
|
||
var encryptedConversationSignature = rawResponse.Headers.GetValues("X-Sydney-EncryptedConversationSignature").FirstOrDefault(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this doesn't work without |
||
|
||
return new( | ||
response.ClientId, | ||
response.ConversationId, | ||
response.ConversationSignature, | ||
_options.Tone); | ||
_options.Tone, | ||
encryptedConversationSignature, | ||
cookies); | ||
} | ||
|
||
/// <summary> | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,5 +1,8 @@ | ||||||
using System.Runtime.CompilerServices; | ||||||
using System.Net; | ||||||
using System.Net.WebSockets; | ||||||
using System.Runtime.CompilerServices; | ||||||
using System.Threading.Channels; | ||||||
using System.Web; | ||||||
using BingChat.Model; | ||||||
using Microsoft.AspNetCore.Connections; | ||||||
using Microsoft.AspNetCore.Http.Connections; | ||||||
|
@@ -18,35 +21,23 @@ namespace BingChat; | |||||
/// </summary> | ||||||
public sealed class BingChatConversation : IBingChattable | ||||||
{ | ||||||
private static readonly HttpConnectionFactory ConnectionFactory = new(Options.Create( | ||||||
new HttpConnectionOptions | ||||||
{ | ||||||
DefaultTransferFormat = TransferFormat.Text, | ||||||
SkipNegotiation = true, | ||||||
Transports = HttpTransportType.WebSockets, | ||||||
Headers = | ||||||
{ | ||||||
["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + | ||||||
"AppleWebKit/537.36 (KHTML, like Gecko) " + | ||||||
"Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.57" | ||||||
} | ||||||
}), | ||||||
NullLoggerFactory.Instance); | ||||||
|
||||||
private static readonly JsonHubProtocol HubProtocol = new( | ||||||
Options.Create(new JsonHubProtocolOptions() | ||||||
{ | ||||||
PayloadSerializerOptions = SerializerContext.Default.Options | ||||||
})); | ||||||
|
||||||
private static readonly UriEndPoint HubEndpoint = new(new Uri("wss://sydney.bing.com/sydney/ChatHub")); | ||||||
private static readonly DefaultRetryPolicy DefaultRetryPolicy = new(); | ||||||
|
||||||
private readonly BingChatRequest _request; | ||||||
|
||||||
private readonly string? _encryptedConversationSignature; | ||||||
private readonly CookieContainer _cookies; | ||||||
internal BingChatConversation( | ||||||
string clientId, string conversationId, string conversationSignature, BingChatTone tone) | ||||||
string clientId, string conversationId, string conversationSignature, BingChatTone tone, string? encryptedConversationSignature, CookieContainer cookies) | ||||||
{ | ||||||
_request = new BingChatRequest(clientId, conversationId, conversationSignature, tone); | ||||||
_encryptedConversationSignature = encryptedConversationSignature; | ||||||
this._cookies = cookies; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
/// <inheritdoc/> | ||||||
|
@@ -99,11 +90,18 @@ public async IAsyncEnumerable<string> StreamAsync( | |||||
// This is best done by extracting formatting logic from one-shot BuildAnswer used by AskAsync. | ||||||
if (messageId != null) | ||||||
{ | ||||||
var completedMessage = response.Result.Messages | ||||||
.First(msg => msg.MessageId == messageId) | ||||||
.Text; | ||||||
if (completedMessage!.Length > completedLength) | ||||||
tx.TryWrite(completedMessage[completedLength..]); | ||||||
if (response.Result.Messages.Any(s => s.MessageType == "Disengaged")) | ||||||
{ | ||||||
tx.TryWrite("Chat Bot Disengaged"); | ||||||
} | ||||||
else | ||||||
{ | ||||||
var completedMessage = response.Result.Messages | ||||||
.First(msg => msg.MessageId == messageId) | ||||||
.Text; | ||||||
if (completedMessage!.Length > completedLength) | ||||||
tx.TryWrite(completedMessage[completedLength..]); | ||||||
} | ||||||
} | ||||||
tx.Complete(); | ||||||
}, ct); | ||||||
|
@@ -169,16 +167,54 @@ public async IAsyncEnumerable<string> StreamAsync( | |||||
return messages.Count > 0 ? string.Join("\n\n", messages) : null; | ||||||
} | ||||||
|
||||||
private static async Task<HubConnection> Connect(CancellationToken ct) | ||||||
private HttpConnectionFactory CreateConnectionFactory() => new(Options.Create( | ||||||
new HttpConnectionOptions | ||||||
{ | ||||||
DefaultTransferFormat = TransferFormat.Text, | ||||||
SkipNegotiation = true, | ||||||
Transports = HttpTransportType.WebSockets, | ||||||
Cookies = _cookies, | ||||||
Headers = | ||||||
{ | ||||||
["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.47", | ||||||
["Origin"] = "https://www.bing.com" | ||||||
} | ||||||
}), | ||||||
NullLoggerFactory.Instance); | ||||||
|
||||||
private async Task<HubConnection> Connect(CancellationToken ct = default) | ||||||
{ | ||||||
var uri = this._encryptedConversationSignature == null | ||||||
? "wss://sydney.bing.com/sydney/ChatHub" | ||||||
: $"wss://sydney.bing.com/sydney/ChatHub?sec_access_token={HttpUtility.UrlEncode(_encryptedConversationSignature)}"; | ||||||
|
||||||
var conn = new HubConnection( | ||||||
ConnectionFactory, | ||||||
CreateConnectionFactory(), | ||||||
HubProtocol, | ||||||
HubEndpoint, | ||||||
new UriEndPoint(new Uri(uri)), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to cache this property instead of creating it on each request. |
||||||
new ServiceCollection().BuildServiceProvider(), | ||||||
NullLoggerFactory.Instance); | ||||||
NullLoggerFactory.Instance, | ||||||
DefaultRetryPolicy); | ||||||
|
||||||
await conn.StartAsync(ct); | ||||||
//Retry on SSL connection error. | ||||||
int retry = 0; | ||||||
while (true) | ||||||
{ | ||||||
try | ||||||
{ | ||||||
await conn.StartAsync(ct); | ||||||
break; | ||||||
} | ||||||
catch (WebSocketException) | ||||||
{ | ||||||
Thread.Sleep(100); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You must never use |
||||||
if (retry < 5) | ||||||
{ | ||||||
retry++; | ||||||
} | ||||||
else throw; | ||||||
} | ||||||
} | ||||||
|
||||||
return conn; | ||||||
} | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.SignalR.Client; | ||
|
||
namespace BingChat | ||
{ | ||
public class DefaultRetryPolicy:IRetryPolicy | ||
{ | ||
public TimeSpan? NextRetryDelay(RetryContext retryContext) | ||
{ | ||
return TimeSpan.FromSeconds(1); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -8,9 +8,12 @@ internal static class Utils | |||||
public static BingChatClient GetClient(BingChatTone tone) | ||||||
{ | ||||||
var cookie = Environment.GetEnvironmentVariable("BING_COOKIE"); | ||||||
var cookieFile = Environment.GetEnvironmentVariable("BING_COOKIES_FILE"); | ||||||
|
||||||
return new BingChatClient(new BingChatClientOptions | ||||||
{ | ||||||
CookieU = string.IsNullOrWhiteSpace(cookie) ? null : cookie, | ||||||
CookieFilePath = string.IsNullOrEmpty(cookieFile)? null: cookieFile, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
Tone = tone, | ||||||
}); | ||||||
} | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please revert all changes in this file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file does not belong to the PR