using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.CompilerServices;
using HarmonyLib;
using Metater.Persistence;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine.Networking;
using UnityEngine.UIElements;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ClaudeBackend")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ClaudeBackend")]
[assembly: AssemblyTitle("ClaudeBackend")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
[BepInPlugin("local.claudebackend", "ClaudeBackend", "1.0.2")]
public class ClaudeBackend : BaseUnityPlugin
{
internal static ConfigEntry<string> Effort;
internal static ConfigEntry<int> MaxTokens;
internal static ManualLogSource Log;
private void Awake()
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Effort = ((BaseUnityPlugin)this).Config.Bind<string>("Claude", "Effort", "low", "Default effort (low | medium | high | xhigh | max) when the model's Verbosity tuning is blank. Lower = faster replies.");
MaxTokens = ((BaseUnityPlugin)this).Config.Bind<int>("Claude", "MaxTokens", 8000, "Minimum max_tokens per reply (thinking counts toward it).");
new Harmony("local.claudebackend").PatchAll(typeof(ClaudeBackend).Assembly);
((BaseUnityPlugin)this).Logger.LogInfo((object)"ClaudeBackend loaded. Pick \"Claude API\" in Host AI settings.");
}
}
internal static class Mode
{
public const string Label = "Claude API";
private const string Flag = "HostAI.ClaudeMode";
private static readonly string[] Prefs = new string[3] { "HostAI.OpenRouterKey", "HostAI.OpenRouterModel", "HostAI.OpenRouterFavorites" };
public static bool Claude => MetaSave.Local.GetInt("HostAI.ClaudeMode", 0) == 1;
public static void Enter()
{
if (!Claude)
{
Swap(".OpenRouter", ".Claude", 1);
}
}
public static void Leave()
{
if (Claude)
{
Swap(".Claude", ".OpenRouter", 0);
}
}
private static void Swap(string stashCurrentAs, string loadFrom, int flag)
{
string[] prefs = Prefs;
foreach (string text in prefs)
{
Move(text, text + stashCurrentAs);
Move(text + loadFrom, text);
}
MetaSave.Local.SetInt("HostAI.ClaudeMode", flag);
MetaSave.Local.Save();
}
private static void Move(string from, string to)
{
string text = MetaSave.Local.GetString(from, string.Empty);
if (string.IsNullOrEmpty(text))
{
MetaSave.Local.DeleteKey(to);
}
else
{
MetaSave.Local.SetString(to, text);
}
MetaSave.Local.DeleteKey(from);
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal static class PanelCtorPatch
{
private static void Postfix(HostAiSettingsPanel __instance)
{
DropdownField value = Traverse.Create((object)__instance).Field<DropdownField>("backend").Value;
((BasePopupField<string, string>)(object)value).choices = ((BasePopupField<string, string>)(object)value).choices.Concat(new string[1] { "Claude API" }).ToList();
Func<string, string> list = ((PopupField<string>)(object)value).formatListItemCallback;
Func<string, string> sel = ((PopupField<string>)(object)value).formatSelectedValueCallback;
((PopupField<string>)(object)value).formatListItemCallback = (string v) => (!(v == "Claude API")) ? list(v) : "Claude API";
((PopupField<string>)(object)value).formatSelectedValueCallback = (string v) => (!(v == "Claude API")) ? sel(v) : "Claude API";
__instance.Refresh();
}
}
[HarmonyPatch(typeof(HostAiSettingsPanel), "BackendChanged")]
internal static class BackendChangedPatch
{
private static bool Prefix(HostAiSettingsPanel __instance, ChangeEvent<string> evt)
{
if (!(evt.newValue == "Claude API"))
{
if (Mode.Claude)
{
Mode.Leave();
PanelUi.Reset(__instance);
}
return true;
}
if (HostAiSettings.CanEdit && !Mode.Claude)
{
Mode.Enter();
if (!HostAiSettings.TrySetBackend(1))
{
Mode.Leave();
ClaudeBackend.Log.LogError((object)"Could not switch backend: is ByokUnlock installed?");
}
else
{
Traverse.Create((object)__instance).Field<Action>("playClick").Value?.Invoke();
}
PanelUi.Reset(__instance);
}
__instance.Refresh();
return false;
}
}
[HarmonyPatch(typeof(HostAiSettingsPanel), "Refresh")]
internal static class RefreshPatch
{
private static string openRouterPlaceholder;
private static string openRouterSearch;
private static void Postfix(HostAiSettingsPanel __instance)
{
Traverse val = Traverse.Create((object)__instance);
if (!val.Field<bool>("disposed").Value)
{
if (Mode.Claude && !HostAiSettings.OpenRouterSelected && HostAiSettings.CanEdit)
{
Mode.Leave();
PanelUi.Reset(__instance);
}
Label value = val.Field<Label>("keyPlaceholder").Value;
if (openRouterPlaceholder == null)
{
openRouterPlaceholder = ((TextElement)value).text;
}
bool flag = Mode.Claude && HostAiSettings.OpenRouterSelected;
((TextElement)value).text = (flag ? "Paste your Claude API key (sk-ant-...)" : openRouterPlaceholder);
Label value2 = val.Field<Label>("searchPlaceholder").Value;
if (openRouterSearch == null)
{
openRouterSearch = ((TextElement)value2).text;
}
((TextElement)value2).text = (flag ? "Search Claude models..." : openRouterSearch);
if (flag)
{
((BaseField<string>)(object)val.Field<DropdownField>("backend").Value).SetValueWithoutNotify("Claude API");
}
}
}
}
internal static class PanelUi
{
public static void Reset(HostAiSettingsPanel panel)
{
Traverse val = Traverse.Create((object)panel);
if (val.Field<CancellationTokenSource>("loading").Value != null)
{
val.Method("CancelLoad", Array.Empty<object>()).GetValue();
}
val.Field<bool>("attemptedLoad").Value = false;
val.Field<List<OpenRouterModel>>("catalog").Value = new List<OpenRouterModel>();
((BaseField<string>)(object)val.Field<TextField>("key").Value).SetValueWithoutNotify(HostAiSettings.ApiKey);
((TextElement)val.Field<Label>("keyStatus").Value).text = (HostAiSettings.HasSavedKey ? "Key saved on this computer." : "Paste your API key.");
((TextElement)val.Field<Label>("status").Value).text = string.Empty;
val.Method("RefreshFavorites", Array.Empty<object>()).GetValue();
val.Method("Filter", Array.Empty<object>()).GetValue();
}
}
[HarmonyPatch(typeof(OpenRouterModelCatalog), "LoadAsync")]
internal static class CatalogPatch
{
private static bool Prefix(CancellationToken cancellationToken, ref UniTask<List<OpenRouterModel>> __result)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
if (!Mode.Claude)
{
return true;
}
__result = Claude.LoadModelsAsync(cancellationToken);
return false;
}
}
[HarmonyPatch(typeof(KolkataApi), "SendDirectOpenRouterAsync")]
internal static class SendDirectPatch
{
private static bool Prefix(JObject body, string key, int timeoutSeconds, CancellationToken cancellationToken, string provider, ref UniTask<JObject> __result)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (provider != "OpenRouter" || !Mode.Claude)
{
return true;
}
__result = Claude.SendAsync(body, key, timeoutSeconds, cancellationToken);
return false;
}
}
internal static class Claude
{
[CompilerGenerated]
private sealed class <>c__DisplayClass4_0
{
public HashSet<string> favorites;
internal bool <LoadModelsAsync>b__1(OpenRouterModel m)
{
return favorites.Contains(m.Id);
}
}
[StructLayout(LayoutKind.Auto)]
[CompilerGenerated]
private struct <LoadModelsAsync>d__4 : IAsyncStateMachine
{
public int <>1__state;
public AsyncUniTaskMethodBuilder<List<OpenRouterModel>> <>t__builder;
public CancellationToken ct;
private string <key>5__2;
private Awaiter<(long, string)> <>u__1;
private void MoveNext()
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
int num = <>1__state;
List<OpenRouterModel> result;
try
{
Awaiter<(long, string)> val;
if (num != 0)
{
<key>5__2 = HostAiSettings.ApiKey;
if (string.IsNullOrWhiteSpace(<key>5__2))
{
throw new InvalidOperationException("Paste your Claude API key, then press Refresh.");
}
val = Send("GET", "models?limit=1000", null, <key>5__2, 20, ct).GetAwaiter();
if (!val.IsCompleted)
{
num = (<>1__state = 0);
<>u__1 = val;
<>t__builder.AwaitUnsafeOnCompleted<Awaiter<(long, string)>, <LoadModelsAsync>d__4>(ref val, ref this);
return;
}
}
else
{
val = <>u__1;
<>u__1 = default(Awaiter<(long, string)>);
num = (<>1__state = -1);
}
var (num2, text) = val.GetResult();
HostAiSettings.RecordKeyResponse(<key>5__2, num2);
if (num2 != 200)
{
throw new InvalidOperationException($"Could not load Claude models (HTTP {num2}): {ErrorMessage(text)}");
}
List<OpenRouterModel> list = ParseModels(text);
if (HostAiSettings.SelectedModel == null && list.Count > 0)
{
OpenRouterModel val2 = ((IEnumerable<OpenRouterModel>)list).FirstOrDefault((Func<OpenRouterModel, bool>)new <>c__DisplayClass4_0
{
favorites = new HashSet<string>(HostAiSettings.FavoriteModels.Select((OpenRouterModel m) => m.Id))
}.<LoadModelsAsync>b__1) ?? ((IEnumerable<OpenRouterModel>)list).FirstOrDefault((Func<OpenRouterModel, bool>)((OpenRouterModel m) => m.Id == "claude-opus-5-5")) ?? list[0];
HostAiSettings.TrySetModel(val2);
ClaudeBackend.Log.LogInfo((object)("No model selected; using " + val2.Id));
}
result = list;
}
catch (Exception exception)
{
<>1__state = -2;
<key>5__2 = null;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<key>5__2 = null;
<>t__builder.SetResult(result);
}
void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
<>t__builder.SetStateMachine(stateMachine);
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
[StructLayout(LayoutKind.Auto)]
[CompilerGenerated]
private struct <Send>d__7 : IAsyncStateMachine
{
public int <>1__state;
public AsyncUniTaskMethodBuilder<(long, string)> <>t__builder;
public string path;
public string method;
public int timeoutSeconds;
public JObject body;
public string key;
public CancellationToken ct;
private UnityWebRequest <request>5__2;
private Awaiter<UnityWebRequest> <>u__1;
private void MoveNext()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
//IL_0049: Expected O, but got Unknown
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Expected O, but got Unknown
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
int num = <>1__state;
(long, string) result;
try
{
if (num != 0)
{
<request>5__2 = new UnityWebRequest("https://api.anthropic.com/v1/" + path, method)
{
timeout = timeoutSeconds,
redirectLimit = 0,
downloadHandler = (DownloadHandler)new DownloadHandlerBuffer()
};
}
try
{
if (num != 0)
{
if (body != null)
{
<request>5__2.uploadHandler = (UploadHandler)new UploadHandlerRaw(Encoding.UTF8.GetBytes(((JToken)body).ToString((Formatting)0, Array.Empty<JsonConverter>())));
<request>5__2.SetRequestHeader("Content-Type", "application/json");
}
<request>5__2.SetRequestHeader("x-api-key", key);
<request>5__2.SetRequestHeader("anthropic-version", "2026-10-21");
JObject obj = body;
if (((obj != null) ? obj["fallbacks"] : null) != null)
{
<request>5__2.SetRequestHeader("anthropic-beta", "server-side-fallback-2026-07-01");
}
}
try
{
Awaiter<UnityWebRequest> val;
if (num != 0)
{
val = UnityAsyncExtensions.ToUniTask(<request>5__2.SendWebRequest(), (IProgress<float>)null, (PlayerLoopTiming)8, ct, false).GetAwaiter();
if (!val.IsCompleted)
{
num = (<>1__state = 0);
<>u__1 = val;
<>t__builder.AwaitUnsafeOnCompleted<Awaiter<UnityWebRequest>, <Send>d__7>(ref val, ref this);
return;
}
}
else
{
val = <>u__1;
<>u__1 = default(Awaiter<UnityWebRequest>);
num = (<>1__state = -1);
}
val.GetResult();
}
catch (UnityWebRequestException)
{
}
if (<request>5__2.responseCode == 0L)
{
throw new KolkataAiServiceException("Claude request failed: " + <request>5__2.error, (string)null, (string)null, (double?)null, (long?)null);
}
result = (<request>5__2.responseCode, <request>5__2.downloadHandler.text);
}
finally
{
if (num < 0 && <request>5__2 != null)
{
((IDisposable)<request>5__2).Dispose();
}
}
}
catch (Exception exception)
{
<>1__state = -2;
<request>5__2 = null;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<request>5__2 = null;
<>t__builder.SetResult(result);
}
void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
<>t__builder.SetStateMachine(stateMachine);
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
[StructLayout(LayoutKind.Auto)]
[CompilerGenerated]
private struct <SendAsync>d__6 : IAsyncStateMachine
{
public int <>1__state;
public AsyncUniTaskMethodBuilder<JObject> <>t__builder;
public JObject openAi;
public string key;
public int timeoutSeconds;
public CancellationToken ct;
private Awaiter<(long, string)> <>u__1;
private void MoveNext()
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
int num = <>1__state;
JObject result;
try
{
Awaiter<(long, string)> val;
if (num != 0)
{
if (num == 1)
{
val = <>u__1;
<>u__1 = default(Awaiter<(long, string)>);
num = (<>1__state = -1);
goto IL_014e;
}
JObject body = ToClaude(openAi, full: true);
val = Send("POST", "messages", body, key, timeoutSeconds, ct).GetAwaiter();
if (!val.IsCompleted)
{
num = (<>1__state = 0);
<>u__1 = val;
<>t__builder.AwaitUnsafeOnCompleted<Awaiter<(long, string)>, <SendAsync>d__6>(ref val, ref this);
return;
}
}
else
{
val = <>u__1;
<>u__1 = default(Awaiter<(long, string)>);
num = (<>1__state = -1);
}
var (num2, text) = val.GetResult();
if (num2 == 400)
{
ClaudeBackend.Log.LogWarning((object)("Claude rejected the request, retrying minimal: " + text));
val = Send("POST", "messages", ToClaude(openAi, full: false), key, timeoutSeconds, ct).GetAwaiter();
if (!val.IsCompleted)
{
num = (<>1__state = 1);
<>u__1 = val;
<>t__builder.AwaitUnsafeOnCompleted<Awaiter<(long, string)>, <SendAsync>d__6>(ref val, ref this);
return;
}
goto IL_014e;
}
goto IL_0163;
IL_014e:
(num2, text) = val.GetResult();
goto IL_0163;
IL_0163:
HostAiSettings.RecordKeyResponse(key, num2);
if (num2 != 200)
{
string text2 = $"Claude request failed (HTTP {num2}): {ErrorMessage(text)}";
long? num3 = num2;
throw new KolkataAiServiceException(text2, (string)null, (string)null, (double?)null, num3);
}
result = ToOpenAi(JObject.Parse(text));
}
catch (Exception exception)
{
<>1__state = -2;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<>t__builder.SetResult(result);
}
void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
}
[DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
<>t__builder.SetStateMachine(stateMachine);
}
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
private const string Api = "https://api.anthropic.com/v1/";
private static readonly Dictionary<string, (decimal In, decimal Out)> Prices = new Dictionary<string, (decimal, decimal)>
{
["claude-fable-5-1"] = (10m, 50m),
["claude-fable-5"] = (10m, 50m),
["claude-opus-5-5"] = (4m, 20m),
["claude-opus-5"] = (5m, 25m),
["claude-opus-4-8"] = (5m, 25m),
["claude-opus-4-7"] = (5m, 25m),
["claude-opus-4-6"] = (5m, 25m),
["claude-sonnet-5-5"] = (2m, 10m),
["claude-sonnet-5"] = (2m, 10m),
["claude-sonnet-4-6"] = (3m, 15m),
["claude-haiku-5-5"] = (0.10m, 0.50m),
["claude-haiku-4-5"] = (1m, 5m)
};
private static readonly HashSet<string> FallbackModels = new HashSet<string> { "claude-fable-5-1", "claude-opus-5-5", "claude-opus-5", "claude-sonnet-5-5" };
private static readonly string[] Supported = new string[4] { "max_tokens", "structured_outputs", "response_format", "verbosity" };
[AsyncStateMachine(typeof(<LoadModelsAsync>d__4))]
public static UniTask<List<OpenRouterModel>> LoadModelsAsync(CancellationToken ct)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
<LoadModelsAsync>d__4 <LoadModelsAsync>d__ = default(<LoadModelsAsync>d__4);
<LoadModelsAsync>d__.<>t__builder = AsyncUniTaskMethodBuilder<List<OpenRouterModel>>.Create();
<LoadModelsAsync>d__.ct = ct;
<LoadModelsAsync>d__.<>1__state = -1;
<LoadModelsAsync>d__.<>t__builder.Start<<LoadModelsAsync>d__4>(ref <LoadModelsAsync>d__);
return <LoadModelsAsync>d__.<>t__builder.Task;
}
internal static List<OpenRouterModel> ParseModels(string json)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
JToken obj = JObject.Parse(json)["data"];
return (from m in ((IEnumerable)(((object)((obj is JArray) ? obj : null)) ?? ((object)new JArray()))).OfType<JObject>()
where OpenRouterModel.IsValidId((string)m["id"])
select m).Select((Func<JObject, OpenRouterModel>)delegate(JObject m)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
string text = (string)m["id"];
(decimal, decimal) value;
return new OpenRouterModel
{
Id = text,
Name = (((string)m["display_name"]) ?? text),
SupportedParameters = Supported,
MaxCompletionTokens = ((int?)m["max_tokens"]).GetValueOrDefault(),
PriceLabel = (Prices.TryGetValue(text, out value) ? string.Format(CultureInfo.InvariantCulture, "${0:0.##} input / ${1:0.##} output per 1M tokens", value.Item1, value.Item2) : "Claude API")
};
}).ToList();
}
[AsyncStateMachine(typeof(<SendAsync>d__6))]
public static UniTask<JObject> SendAsync(JObject openAi, string key, int timeoutSeconds, CancellationToken ct)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
<SendAsync>d__6 <SendAsync>d__ = default(<SendAsync>d__6);
<SendAsync>d__.<>t__builder = AsyncUniTaskMethodBuilder<JObject>.Create();
<SendAsync>d__.openAi = openAi;
<SendAsync>d__.key = key;
<SendAsync>d__.timeoutSeconds = timeoutSeconds;
<SendAsync>d__.ct = ct;
<SendAsync>d__.<>1__state = -1;
<SendAsync>d__.<>t__builder.Start<<SendAsync>d__6>(ref <SendAsync>d__);
return <SendAsync>d__.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<Send>d__7))]
private static UniTask<(long, string)> Send(string method, string path, JObject body, string key, int timeoutSeconds, CancellationToken ct)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
<Send>d__7 <Send>d__ = default(<Send>d__7);
<Send>d__.<>t__builder = AsyncUniTaskMethodBuilder<(long, string)>.Create();
<Send>d__.method = method;
<Send>d__.path = path;
<Send>d__.body = body;
<Send>d__.key = key;
<Send>d__.timeoutSeconds = timeoutSeconds;
<Send>d__.ct = ct;
<Send>d__.<>1__state = -1;
<Send>d__.<>t__builder.Start<<Send>d__7>(ref <Send>d__);
return <Send>d__.<>t__builder.Task;
}
internal static JObject ToClaude(JObject src, bool full)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Expected O, but got Unknown
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Expected O, but got Unknown
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Expected O, but got Unknown
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0200: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: Expected O, but got Unknown
//IL_023b: Unknown result type (might be due to invalid IL or missing references)
//IL_0240: Unknown result type (might be due to invalid IL or missing references)
//IL_0255: Unknown result type (might be due to invalid IL or missing references)
//IL_0267: Expected O, but got Unknown
StringBuilder stringBuilder = new StringBuilder();
JArray val = new JArray();
JToken obj = src["messages"];
foreach (JObject item in ((IEnumerable)(((object)((obj is JArray) ? obj : null)) ?? ((object)new JArray()))).OfType<JObject>())
{
string text = (string)item["role"];
string text2 = Text(item["content"]);
if (text == "system" || text == "developer")
{
Append(stringBuilder, text2);
}
else if (!string.IsNullOrEmpty(text2))
{
val.Add((JToken)new JObject
{
["role"] = JToken.op_Implicit((text == "assistant") ? "assistant" : "user"),
["content"] = JToken.op_Implicit(text2)
});
}
}
if (((JContainer)val).Count == 0 || (string)((JToken)val).Last[(object)"role"] == "assistant")
{
val.Add((JToken)new JObject
{
["role"] = JToken.op_Implicit("user"),
["content"] = JToken.op_Implicit("Continue.")
});
}
string text3 = (string)src["model"];
JToken obj2 = src["response_format"];
JObject val2 = (JObject)(object)((obj2 is JObject) ? obj2 : null);
object obj3;
if (val2 == null)
{
obj3 = null;
}
else
{
JToken obj4 = val2["json_schema"];
obj3 = ((obj4 != null) ? obj4[(object)"schema"] : null);
}
JObject val3 = (JObject)((obj3 is JObject) ? obj3 : null);
JObject val4 = new JObject
{
["model"] = JToken.op_Implicit(text3),
["max_tokens"] = JToken.op_Implicit(Math.Max(((int?)src["max_tokens"]).GetValueOrDefault(), ClaudeBackend.MaxTokens.Value)),
["messages"] = (JToken)(object)val
};
if (full)
{
JObject val5 = new JObject { ["effort"] = JToken.op_Implicit(((string)src["verbosity"]) ?? ClaudeBackend.Effort.Value) };
if (val3 != null)
{
val5["format"] = (JToken)new JObject
{
["type"] = JToken.op_Implicit("json_schema"),
["schema"] = (JToken)(object)val3
};
}
val4["output_config"] = (JToken)(object)val5;
if (FallbackModels.Contains(text3))
{
val4["fallbacks"] = JToken.op_Implicit("default");
}
}
if (val3 != null && !full)
{
Append(stringBuilder, "Reply with only a JSON object matching this schema, no markdown:\n" + ((JToken)val3).ToString((Formatting)0, Array.Empty<JsonConverter>()));
}
else if (val3 == null && (string)((val2 != null) ? val2["type"] : null) == "json_object")
{
Append(stringBuilder, "Reply with only a valid JSON object, no markdown.");
}
if (stringBuilder.Length > 0)
{
val4["system"] = JToken.op_Implicit(stringBuilder.ToString());
}
return val4;
}
internal static JObject ToOpenAi(JObject res)
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Expected O, but got Unknown
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Expected O, but got Unknown
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Expected O, but got Unknown
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Expected O, but got Unknown
//IL_021b: Expected O, but got Unknown
string text = (string)res["stop_reason"];
if (text == "refusal")
{
JToken obj = res["stop_details"];
throw new KolkataAiServiceException("Claude declined this request (" + (string)((obj != null) ? obj[(object)"category"] : null) + ").", (string)null, (string)null, (double?)null, (long?)null);
}
JToken obj2 = res["content"];
string text2 = StripFence(string.Concat(from b in (IEnumerable<JToken>)(((object)((obj2 is JArray) ? obj2 : null)) ?? ((object)new JArray()))
where (string)b[(object)"type"] == "text"
select (string)b[(object)"text"]));
if (text2.Length == 0)
{
throw new KolkataAiServiceException("Claude returned no text (stop_reason " + text + ").", (string)null, (string)null, (double?)null, (long?)null);
}
JObject val = new JObject
{
["id"] = res["id"],
["model"] = res["model"],
["choices"] = (JToken)new JArray((object)new JObject
{
["index"] = JToken.op_Implicit(0),
["message"] = (JToken)new JObject
{
["role"] = JToken.op_Implicit("assistant"),
["content"] = JToken.op_Implicit(text2)
},
["finish_reason"] = JToken.op_Implicit((text == "max_tokens") ? "length" : "stop")
})
};
JObject val2 = new JObject();
JToken obj3 = res["usage"];
val2["prompt_tokens"] = ((obj3 != null) ? obj3[(object)"input_tokens"] : null);
JToken obj4 = res["usage"];
val2["completion_tokens"] = ((obj4 != null) ? obj4[(object)"output_tokens"] : null);
val["usage"] = (JToken)val2;
return val;
}
private static string Text(JToken content)
{
if (content != null)
{
JArray val = (JArray)(object)((content is JArray) ? content : null);
if (val != null)
{
return string.Join("\n", from p in ((IEnumerable)val).OfType<JObject>()
where p["text"] != null
select (string)p["text"]);
}
return ((string)content) ?? "";
}
return "";
}
private static void Append(StringBuilder sb, string s)
{
if (!string.IsNullOrEmpty(s))
{
if (sb.Length > 0)
{
sb.Append("\n\n");
}
sb.Append(s);
}
}
private static string StripFence(string t)
{
t = t.Trim();
if (!t.StartsWith("```"))
{
return t;
}
int num = t.IndexOf('\n');
int num2 = t.LastIndexOf("```", StringComparison.Ordinal);
if (num <= 0 || num2 <= num)
{
return t;
}
return t.Substring(num + 1, num2 - num - 1).Trim();
}
private static string ErrorMessage(string body)
{
try
{
JToken obj = JObject.Parse(body)["error"];
return ((string)((obj != null) ? obj[(object)"message"] : null)) ?? body;
}
catch (JsonException)
{
return body;
}
}
}