zc
This commit is contained in:
@@ -15,15 +15,6 @@
|
||||
{
|
||||
"name": "dll1.6",
|
||||
"path": "../../../../dll1.6"
|
||||
},
|
||||
{
|
||||
"path": "../../../../../../../../Users/Kalo/Downloads/RimTalk-main"
|
||||
},
|
||||
{
|
||||
"path": "../../../../../../../../Users/Kalo/Downloads/openai_token-main"
|
||||
},
|
||||
{
|
||||
"path": "../../../../../../workshop/content/294100/3622974806"
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire.EventSystem.AI
|
||||
@@ -21,7 +22,7 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
_model = model;
|
||||
}
|
||||
|
||||
public async Task<string> GetChatCompletionAsync(string instruction, List<(string role, string message)> messages)
|
||||
public async Task<string> GetChatCompletionAsync(string instruction, List<(string role, string message)> messages, int? maxTokens = null, float? temperature = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_baseUrl))
|
||||
{
|
||||
@@ -39,6 +40,15 @@ namespace WulaFallenEmpire.EventSystem.AI
|
||||
jsonBuilder.Append("{");
|
||||
jsonBuilder.Append($"\"model\": \"{_model}\",");
|
||||
jsonBuilder.Append("\"stream\": false,"); // We request non-stream, but handle stream if returned
|
||||
if (maxTokens.HasValue)
|
||||
{
|
||||
jsonBuilder.Append($"\"max_tokens\": {Math.Max(1, maxTokens.Value)},");
|
||||
}
|
||||
if (temperature.HasValue)
|
||||
{
|
||||
float clamped = Mathf.Clamp(temperature.Value, 0f, 2f);
|
||||
jsonBuilder.Append($"\"temperature\": {clamped.ToString("0.###", System.Globalization.CultureInfo.InvariantCulture)},");
|
||||
}
|
||||
jsonBuilder.Append("\"messages\": [");
|
||||
|
||||
// System instruction
|
||||
|
||||
@@ -5,6 +5,8 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Verse;
|
||||
using System.Text.RegularExpressions;
|
||||
using WulaFallenEmpire.EventSystem.AI.UI;
|
||||
|
||||
namespace WulaFallenEmpire.EventSystem.AI.Tools
|
||||
{
|
||||
@@ -91,6 +93,13 @@ namespace WulaFallenEmpire.EventSystem.AI.Tools
|
||||
idx++;
|
||||
}
|
||||
|
||||
string toolHistory = BuildToolHistory(count);
|
||||
if (!string.IsNullOrWhiteSpace(toolHistory))
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.AppendLine(toolHistory);
|
||||
}
|
||||
|
||||
return sb.ToString().TrimEnd();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -99,6 +108,54 @@ namespace WulaFallenEmpire.EventSystem.AI.Tools
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildToolHistory(int maxCount)
|
||||
{
|
||||
var window = Dialog_AIConversation.Instance ?? Find.WindowStack.WindowOfType<Dialog_AIConversation>();
|
||||
if (window == null) return "AI Tool History: none found.";
|
||||
|
||||
var history = window.GetHistorySnapshot();
|
||||
if (history == null || history.Count == 0) return "AI Tool History: none found.";
|
||||
|
||||
var entries = new List<(string ToolXml, string ToolResult)>();
|
||||
for (int i = history.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var entry = history[i];
|
||||
if (!string.Equals(entry.role, "tool", StringComparison.OrdinalIgnoreCase)) continue;
|
||||
|
||||
string toolResult = entry.message ?? "";
|
||||
for (int j = i - 1; j >= 0; j--)
|
||||
{
|
||||
var prev = history[j];
|
||||
if (string.Equals(prev.role, "assistant", StringComparison.OrdinalIgnoreCase) && IsXmlToolCall(prev.message))
|
||||
{
|
||||
entries.Add((prev.message ?? "", toolResult));
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entries.Count >= maxCount) break;
|
||||
}
|
||||
|
||||
if (entries.Count == 0) return "AI Tool History: none found.";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < entries.Count; i++)
|
||||
{
|
||||
if (i > 0) sb.AppendLine();
|
||||
sb.AppendLine(entries[i].ToolXml.Trim());
|
||||
sb.AppendLine(entries[i].ToolResult.Trim());
|
||||
}
|
||||
|
||||
return sb.ToString().TrimEnd();
|
||||
}
|
||||
|
||||
private static bool IsXmlToolCall(string response)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(response)) return false;
|
||||
return Regex.IsMatch(response, @"<([a-zA-Z0-9_]+)(?:>.*?</\1>|/>)", RegexOptions.Singleline);
|
||||
}
|
||||
|
||||
private static IEnumerable<NotificationEntry> ReadLetters(int fallbackNow)
|
||||
{
|
||||
var list = new List<NotificationEntry>();
|
||||
@@ -253,4 +310,3 @@ namespace WulaFallenEmpire.EventSystem.AI.Tools
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -146,6 +146,29 @@ namespace WulaFallenEmpire.EventSystem.AI.Utils
|
||||
}
|
||||
}
|
||||
|
||||
// Allow CJK subsequence matches (e.g. "零件" matches "零部件").
|
||||
if (!string.IsNullOrEmpty(normalizedQuery) && normalizedQuery.Length >= 2 && IsCjkString(normalizedQuery))
|
||||
{
|
||||
int bestTargetLen = 0;
|
||||
if (IsCjkString(normalizedLabel) && IsCjkSubsequence(normalizedQuery, normalizedLabel))
|
||||
{
|
||||
bestTargetLen = normalizedLabel.Length;
|
||||
}
|
||||
if (IsCjkString(normalizedDefName) && IsCjkSubsequence(normalizedQuery, normalizedDefName))
|
||||
{
|
||||
if (bestTargetLen == 0 || normalizedDefName.Length < bestTargetLen)
|
||||
{
|
||||
bestTargetLen = normalizedDefName.Length;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestTargetLen > 0)
|
||||
{
|
||||
float coverage = (float)normalizedQuery.Length / Math.Max(1, bestTargetLen);
|
||||
score = Math.Max(score, 0.50f + 0.30f * coverage);
|
||||
}
|
||||
}
|
||||
|
||||
bool queryLooksLikeFood =
|
||||
tokens.Any(t => t == "meal" || t == "food" || t.Contains("meal") || t.Contains("food")) ||
|
||||
lowerQuery.Contains("\u996D") || // 饭
|
||||
@@ -243,6 +266,27 @@ namespace WulaFallenEmpire.EventSystem.AI.Utils
|
||||
(c >= '\uF900' && c <= '\uFAFF');
|
||||
}
|
||||
|
||||
private static bool IsCjkString(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s)) return false;
|
||||
for (int i = 0; i < s.Length; i++)
|
||||
{
|
||||
if (!IsCjkChar(s[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsCjkSubsequence(string query, string target)
|
||||
{
|
||||
if (string.IsNullOrEmpty(query) || string.IsNullOrEmpty(target)) return false;
|
||||
int qi = 0;
|
||||
for (int ti = 0; ti < target.Length && qi < query.Length; ti++)
|
||||
{
|
||||
if (target[ti] == query[qi]) qi++;
|
||||
}
|
||||
return qi == query.Length;
|
||||
}
|
||||
|
||||
private static string NormalizeKey(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s)) return "";
|
||||
@@ -253,4 +297,3 @@ namespace WulaFallenEmpire.EventSystem.AI.Utils
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# ----------------------------------------------------------------
|
||||
# 功能: 为 Gemini CLI 设置必要的环境变量
|
||||
# 文件名: setup-gemini-env.ps1
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# 1. 设置代理服务器
|
||||
# 同时为 http 和 https 设置代理是一个好习惯
|
||||
Write-Host "正在设置代理..."
|
||||
$env:http_proxy = "http://127.0.0.1:52053"
|
||||
$env:https_proxy = "http://127.0.0.1:52053"
|
||||
|
||||
# 2. 设置 Google Cloud 项目 ID
|
||||
Write-Host "正在设置 Google Cloud 项目 ID..."
|
||||
$env:GOOGLE_CLOUD_PROJECT = "849717647345"
|
||||
|
||||
# 3. 提示用户操作完成
|
||||
Write-Host ""
|
||||
Write-Host "环境变量设置完成!" -ForegroundColor Green
|
||||
Write-Host "您现在可以在此 PowerShell 窗口中直接运行 'gemini' 命令了。"
|
||||
Write-Host "例如: gemini prompt '天空为什么是蓝色的?'"
|
||||
Reference in New Issue
Block a user