ChatWindow-API

经验创意 · 1442 次浏览
H-D-G 创建于 2024-04-27 11:53

在V50版本中,ChatWindow支持使用表达式来自定义快捷操作(使用ChatWindow对象访问静态方法和字段),并内置了一些我个人会用到的操作,也欢迎各位在本帖下方分享脚本,相互交流学习😁

下表是HDG整理出来的一些常用字段及方法,供参考:

常用字段
名称 类型 说明
win Window 主窗口
context ActionExecuteContext 动作上下文对象
eval EvalContext 执行表达式的上下文对象
meetings ObservableCollection 一个会议信息的集合,是用于存储和管理会议数据
userInfo UserInfo 表示用户信息的对象,包含用户的头像等信息
userSettings UserSettings 用户的设置信息,包括偏好设置等信息
meeting_listbox ListBox 一个列表框控件,用于显示会议列表
input TextEditor 文本编辑器控件,用于输入文本
chatViewer ScrollViewer 滚动视图控件,用于聊天界面的消息滚动
Meeting_Search SearchBar 搜索栏,用于搜索会议信息
store_search SearchBar 搜索栏,用于搜索角色
hotkey HotKeySetting 快捷键设置,用于配置内置快捷键
meeting_listbox_menu ContextMenu 上下文菜单,会议列表框的右键菜单,包含删除话会等菜单项
action ActionItem ChatWindow的ActionItem对象
SwitchBlock TabControl 选项卡控件,用于切换主视图(聊天界面、角色商店等)
SettingTab TabControl 设置选项卡,用于切换配置视图(动作信息、设置界面等)
Tab_bar ListBox 标签栏,用于导航不同的视图
textArea TextArea 文本区域控件,input的TextArea
completionWindow CompletionWindow 补全窗口,用于常用语补全
chatCompleteSetting ChatCompleteSetting 常用语设置,用于配置常用语的相关设置
ChatCompleteData_ListBox ListBox 列表框,可能用于显示聊天自动完成数据
chatContainer ItemsControl 对话容器,由于展示对话
cts CancellationTokenSource 请求服务的取消令牌源
HideMeetingBtn ToggleButton 切换按钮,可能用于隐藏或显示话会选择区域
OldActionVersion int 整数,表示旧的动作版本号
CurrentActionVersion int 整数,表示当前的动作版本号

 

常用方法
名称 返回类型 方法签名 说明
AddText void (string text) 向聊天输入框添加文本
ShowCompletionWindow void () 显示自动补全窗口
AddCompleteData void (ChatCompleteData data) 向自动补全窗口添加数据
OnButtonClicked bool (string name, object tag = null, Window rwin = null, IDictionary<string, object> winData = null, ICustomWindowContext winContext = null) 按钮点击事件处理,执行相应操作,可以传入的name来执行对应的操作
KeyClear void (OperationScript script) 清除快捷键信息
EditScript void (OperationScript script) 设置脚本编辑状态
RemoveScript void (OperationScript script) 从脚本列表中移除指定脚本
AddScript void (OperationScript main, string script = "", Hotkey key = null) 添加新脚本到脚本列表
ExpressionToStep void (string expression) 将表达式转换为步骤并复制到剪贴板
AddAPIServe void (APIServe Data) 添加新的API服务信息
AddChatCompleteData void (ChatCompleteData Data) 添加新的补全数据
RemoveAPIServe void (APIServe Data) 从服务列表中移除API服务
RemoveChatCompleteData void (ChatCompleteData Data) 从补全数据列表中移除指定数据
ChangChar void () 更改补全触发字符
SaveMeeting void (MeetingInfo meet, int index = -1) 保存会议信息
ClearMeetingData MeetingInfo (MeetingInfo meet = null, bool showMessage = true, int group = -1) 清除会议数据
Save void () 保存当前会议数据到文件
SettingFileExport void () 导出设置信息到文件
SettingFileImport void () 从文件导入设置信息
AddMeeting void (MeetingInfo meeting = null, int index = -1) 添加新的会议
SelectMeet void (int index) 选中特定的会议
DeleteMeeting void (MeetingInfo meet = null) 删除特定的会议
GetMeeting MeetingInfo (int index = -1, bool showError = true) 获取特定的会议信息
Chat void (string msg) 发送聊天消息
SendAsyncRequest void (string msg, MeetingInfo meeting) 异步发送聊天请求
Copy T <T>(T source) 创建对象的副本
GetWinHandle IntPtr () 获取窗口句柄
SwitchToNthFromEndTab void (int n) 切换到标签页控件的倒数第n个标签页(从1开始)
GetWinSize string () 获取窗口的大小信息
StrToImg ImageSource (string str) 将字符串转换为ImageSource对象
ToChatCompleteDataByStr ChatCompleteData (string str) 将字符串转换为ChatCompleteData对象
ToStrByChatCompleteData string (ChatCompleteData oldData) 将ChatCompleteData对象转换为字符串
ToCompleteDataList ObservableCollection<ChatCompleteData> (string str) 将字符串转换为ChatCompleteData的集合
ToCompleteDataListStr string (ObservableCollection<ChatCompleteData> dataList) 将ChatCompleteData的集合转换为字符串
SetSelectedItems void (ListBox listBox, IEnumerable<object> selectedItems) 设置ListBox选定的项目
API_SearchRole ObservableCollection<MeetingInfo> (string text = "") 异步搜索角色信息
ScrollToItem void (ChatData item) 滚动到指定的聊天项
GetHistoryItems ObservableCollection<Dictionary<string, object>> (MeetingInfo meeting = null) 获取历史记录项
LineToSpace string (string text) 将字符串中的换行符转换为空白符
GetServe APIServe (string id) 通过ID获取API服务信息
Show void () 显示窗口,如果最小化则恢复
Hide void (bool showInTaskBar = true) 隐藏窗口
 

类型定义:

     public class ChatData : INotifyPropertyChanged
    {
        private string _role;
        private string _content;

        public string role
        {
            get { return _role; }
            set
            {
                if (_role != value)
                {
                    _role = value;
                    OnPropertyChanged(nameof(role));
                }
            }
        }

        public string content
        {
            get { return _content; }
            set
            {
                if (_content != value)
                {
                    _content = value;
                    OnPropertyChanged(nameof(content));
                }
            }
        }

        public ChatData(string content, string role = "user")
        {
            _content = content;
            _role = role;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class MeetingInfo
    {
        public string Title { get; set; }
        public string Desc { get; set; }
        public string Icon { get; set; }
        public ObservableCollection<ChatData> Data { get; set; }
        public ObservableCollection<string> Tags { get; set; } = new ObservableCollection<string>();
        public ModelInfo ModelInfo { get; set; }
        public string ServeId { get; set; }
        public string Id { get; set; }

        public MeetingInfo(string title, ObservableCollection<ChatData> data, string icon = "https://files.getquicker.net/_icons/9FD1890C7ACA84ED0E603C5B46F4BC633436E425.png", ModelInfo modelInfo = null, string desc = "")
        {
            this.Title = title;
            this.Desc = desc;
            this.Data = data;
            this.ModelInfo = modelInfo ?? new ModelInfo();
            this.Icon = icon;
            if (string.IsNullOrWhiteSpace(this.Id)) this.Id = Guid.NewGuid().ToString();
        }
    }
    
    public class ModelInfo
    {
        public string Model { get; set; } = "gpt-3.5-turbo";
        public int MaxTokens { get; set; } = 0;
        public double Temperature { get; set; } = 0.5;
        public int MaxHistory { get; set; } = 4;
        public string SystemMessage { get; set; } = "";
    }
    
    public class UserInfo
    {
        public string Avatar { get; set; }
    }
    
    public class UserSettings
    {
        public bool IsLock { get; set; }
        public HotKeySetting HotKey { get; set; }
    }
    
    public class HotKeySetting
    {
        public bool UseEnterSend { get; set; } = true;
    }
    
    public class ChatCompleteData : ICompletionData
    {
        public string Text { get; set; } = "";

        public object Content { get; set; } = "";

        public object Description { get; set; } = "";

        public double Priority { get; set; } = 0;

        public ObservableCollection<string> Tags { get; set; } = new ObservableCollection<string>();

        public ImageSource Image { get; set; } = null;
        
        public string ImgStr { get; set; } = "fa:Regular_Text";

        public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs)
        {
            int segmentStartOffset = completionSegment.Offset - 1;
            int segmentEndOffset = completionSegment.EndOffset;

            textArea.Document.Replace(segmentStartOffset, segmentEndOffset - segmentStartOffset, Text);
            textArea.Caret.Offset = segmentStartOffset + Text.Length;
        }
        
        public ChatCompleteData(string text, object content, string description, ImageSource img, double priority = 0)
        {
            this.Text = text;
            this.Content = content;
            this.Description = description;
            this.Priority = priority;
            this.Image = img;
        }
    }
    
    public class ChatCompleteSetting
    {
        public bool IsEnabled { get; set; } = false;
        public ObservableCollection<string> TriggerChar { get; set; } = new ObservableCollection<string>();
    }
    
    public class APIServe
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public string ApiKey { get; set; }
        public string ApiUrl { get; set; }
        public string Proxy { get; set; }
        public ServeType ServeType { get; set; }
        public string Id;
        
        public APIServe(string title, string key, string url, string proxy = null, ServeType type = ServeType.ChatGPT)
        {
            this.Title = title;
            this.ApiKey = key;
            this.ApiUrl = url;
            this.Proxy = proxy;
            this.ServeType = type;
            this.Id = Guid.NewGuid().ToString();
        }
    }
    
    public class OperationScript
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public string Script { get; set; }
        public string KeyData { get; set; }
        public string KeyString { get; set; }
        public string Id;
        
        public OperationScript(string title, string script, string key, string desc = "")
        {
            this.Title = title;
            this.Script = script;
            this.KeyData = key;
            this.Id = Guid.NewGuid().ToString();
            this.Description = desc;
        }
    }

    public enum ServeType
    {
        ChatGPT
    }

注意事项:
  1. 脚本会在UI线程上运行,需考虑线程安全
  2. 允许为多个操作设置相同的快捷键,执行时会按顺序触发
  3. ChatWindow对象为全局注册,在其他动作的表达式中也可以访问
H-D-G 最后更新于 2024/4/30

回复内容
Mr.差不多 2024-04-28 08:41
#1

表格的配色太差了,根本看不清

H-D-G 回复 Mr.差不多 2024-04-28 21:30 :

不好意思,我用了浏览器暗色扩展,忘了qk网站是白色背景了😂,等五一改下

H-D-G 2024-04-30 18:19
#2
回复 Mr.差不多 :

表格的配色太差了,根本看不清

已修改

H-D-G 2024-05-12 16:22
#3

脚本分享

H-D-G 回复 H-D-G 2024-05-12 16:23 :

切换上一话会(可循环):
$=
var listbox = ChatWindow.meeting_listbox;
if (listbox.SelectedIndex == 0)
{
    listbox.SelectedIndex = ChatWindow.meetings.Count() - 1;
}
else
{
    listbox.SelectedIndex -= 1;
}

切换下一话会(可循环):

$=var listbox = ChatWindow.meeting_listbox;
if (listbox.SelectedIndex == ChatWindow.meetings.Count() - 1)
{
    listbox.SelectedIndex = 0;
}
else
{
    listbox.SelectedIndex += 1;
}


H-D-G 最后更新于 2024-05-12 16:24
H-D-G 回复 H-D-G 2024-05-12 16:25 :

收起/展开话会选择区域:

$=var btn = ChatWindow.win.FindName("HideMeetingBtn");
btn.IsChecked = !btn.IsChecked;

H-D-G 回复 H-D-G 2024-05-12 16:25 :

打开设置:

$=ChatWindow.SwitchToNthFromEndTab(1)

H-D-G 回复 H-D-G 2024-05-12 16:25 :

添加新话会:

$=ChatWindow.AddMeeting()

H-D-G 回复 H-D-G 2024-06-02 02:01 :

添加问候语:

$=var data = ChatWindow.GetMeeting().Data;
if (data.FirstOrDefault()?.Role != "assistant")
{
    string text = ChatWindow.ShowUserInput("添加问候语");
    if (!text.IsNullOrWhiteSpace())
    {
        data.Insert(0, new ChatData(text, "assistant"));
    }
}

H-D-G 回复 H-D-G 2024-06-02 02:01 :

移除问候语:

$=var meet = ChatWindow.GetMeeting();
if (meet.Data.Any())
{
    if (meet.Data[0].Role == "assistant")
    {
        meet.Data.RemoveAt(0);
    }
}

H-D-G 最后更新于 2024-06-02 02:02
原++ 2024-07-11 17:29
#4

自己有两个API服务,两个key,如何做到当前会话的API服务快速切换呢?

H-D-G 回复 原++ 2024-07-11 17:31 :

是想问如何写脚本来切换吗?

原++ 回复 H-D-G 2024-07-11 17:34 :

希望能通过快捷键和点击默认服务这里能够快速切换,两个都能支持更好啦?当然看作者您的时间和想法吧

H-D-G 回复 原++ 2024-07-11 17:36 :

点击文字估计是不行(那里只是方便查看话会的服务),快捷键可以用脚本的形式解决。

不过我的建议是在创建一个话会,然后保持其他属性不变,只改变服务(因为一开始就是这样设计的)

原++ 回复 H-D-G 2024-07-11 17:37 :

嗯嗯好的,谢谢,我先用您说的那个方法吧。

H-D-G 回复 原++ 2024-07-11 17:38 :

脚本需要的话和我说一声,我去研究下(设计一个脚本功能就是在一些个性化比较高的功能上可以不用更新动作)

原++ 回复 H-D-G 2024-07-28 09:53 :

你好,希望可以增加支持一下用快捷键切换API服务,因为是一个是免费的key,想在免费的key3次gpt-4o用完的时候切换成付费的key。谢谢。

H-D-G 回复 原++ 2024-08-02 22:36 :

借帖回复一下你的问题(私信会报错,很奇怪:

ChatWindow有预留接口,为动作传递json格式的参数即可快捷提问:

{

    "Id" : "这里填话会的id",

    "Text" : "这里填发送给AI的内容"

}

H-D-G 最后更新于 2024-08-02 22:55
H-D-G 回复 原++ 2024-08-02 22:52 :

目前不打算把选中文本发送到AI加到动作里(因为默认运行是打开窗口),你可以用新建一个动作,用为动作传参的形式实现,参数格式在上一层楼(如果对ChatWindow的API比较熟悉,也可以使用表达式,比如:$=ChatWindow.Chat({text}); 这个会把提供的{text}发送给AI,所以你只要获取选中文本,然后给ChatWindow发送表达式或者上面提到的json就行)。

H-D-G 最后更新于 2024-08-02 22:55
原++ 回复 H-D-G 2024-08-04 10:16 :


谢谢回答,但是我传递后,运行失败,解析表达式出错,是否哪里搞错了吗?

H-D-G 回复 原++ 2024-08-04 10:21 :

要把表达式放在变量默认值里,避免提前解析,你这样写,表达式会在动作执行,然后把执行后的结果作为参数传给chatwindow

回复主贴