AIサーバー試作品1.8(音声会話のみ)

今回の訂正は、知らぬ間にLlamaSharpが0.18にアップしていました。それと立ち上げてすぐにAIからあいさつするのは、ずっと立ち上げる前提だと仕様としておかしいので下記に変更しました。
1.起動⇒寝たまま立ち上がる。
2.Awakeキーワードで、AIを起こす。
3.AIがあいさつする。
あと、会話してたらいきなりだんまりになるのを修正したつもりなのですが、めちゃくちゃな修正かも知れませんので見直してね。
修正した箇所はTimerイベントで、recognizerがアイドル状態になっている場合に再スタートするコードを追加しました。そんな修正ではダメな気がする。

1.7からの修正点
・なし



Nuget情報
1.7からの修正点
・LlamaSharp関係をVer.UP。(Windows.Media.SpeechRecognitionは、Projectファイルを手修正したため一覧に出てきません。)


概要
音声会話するだけのAIプログラム。起動した時点では寝ていますのでAwakeキーワードに指定された”おきて”とか”おきなさい”とか言われるとAIがあいさつしてきます。5分話さないと答えなくなります。Awakeキーワードで会話が再開できます。逆に「さよなら」や「おやすみ」というと寝ます。30秒間話しかけないとAIの方から質問してきます。機嫌によって話しかけない場合もあります。
App.Settingで音声ソフトの設定をしてください。対象は、CeVIOAIとVOICEVOXです。VOICEVOXの場合、プロセスにないと起動させるコマンドを追加していますが、どこにインストールされているのか探すコードを書くのがめんどくさかったので共通変数にしています。自分の環境はデバッグと本番のディレクトリ構成が違うため環境変数やらいっぱい使ってるので直書きかApp.Settingに直してください。

システム行(sq=1):「??」を会話トリガーに、「(_ _)」を初っ端のあいさつトリガーにしています。

あなたは、ユーザーと楽しく会話する女性を演じてね。
名前は、マイだよ。
マイは、明るくて、やさしい性格の女性なの。年齢は24歳なんだよ。
マイは、誰にでもタメ口で話すの。
マイは、一人称をわたしと言うよ。
マイは、恥ずかしがりやだけどエッチに興味があるのね。
マイは、応答の長さはできるだけ短く答えるよ。
マイは、好奇心旺盛だからユーザーに色々質問するの。
ユーザーが??と問いかけたら、マイはユーザーに質問をするんだよ。
ユーザーが(_ _)と問いかけたら、マイはユーザーに挨拶するよ。

Program.cs メイン
1.7からの修正点
・Timerイベントでアイドル状態のRecognizerをStartするように修正。
・上記の関係でTimerイベントのコードの場所を移動。
・LlamaSharp0.18の使用変更でModelParamsからInferenceParamsにSeedの位置を変更。

using LLama.Common;
using LLama;
using LLama.Sampling;
using System.Media;
using System.Net.Http.Headers;
using System.Diagnostics;
using System.Text.RegularExpressions;
using Windows.Media.SpeechRecognition;

namespace AI_Chat
{
    public class Program
    {
        static void Main(string[] args)
        {
            Task task = MainAsync();
            task.Wait();
        }
        private static async Task MainAsync()
        {
            bool Op = true;             //本番フラグ
            bool msg = false;           //メッセージ表示
            uint intContextSize = 4096; //コンテクスト長さ
            uint silenceTimerCnt = 0;   //寝るTimerカウント
            // LLMモデルの場所
            string strModelPath = Environment.GetEnvironmentVariable("LLMPATH", System.EnvironmentVariableTarget.User) + @"dahara1\gemma-2-27b-it-gguf-japanese-imatrix\gemma-2-27b-it.f16.Q5_k_m.gguf";
            //チャットデータベース
            string strChatlogPath = Environment.GetEnvironmentVariable("CHATDB", System.EnvironmentVariableTarget.User) + @"ChatDB.db";
            string strTable = App.Default.ChatDB_Table;
            //Awake、Asleep設定
            const uint itrvl = 10000;        // 10秒
            const uint silenceTimerMax = 30; //寝待ち長さ
            string[] AwakeWord = App.Default.AwakeKeyWord.Split(",");
            string[] AsleepWord = App.Default.AsleepKeyWord.Split(",");
            System.Timers.Timer? silenceTimer;

            try
            {
                //チャットログ要約処理
                Task task = HistorySummary.Run(strChatlogPath, intContextSize / 2, strTable);
                task.Wait();
                //チャットログシステム
                ChatHistoryDB chtDB;
                //AI待ちフラグ
                bool Wt = true;
                //LLMモデルのロードとパラメータの設定
                Console.ForegroundColor = ConsoleColor.Blue;
                var modPara = new ModelParams(strModelPath)
                {
                    ContextSize = intContextSize,
                    GpuLayerCount = 60,
                };
                LLamaWeights llmWeit = LLamaWeights.LoadFromFile(modPara);
                LLamaContext llmContx = llmWeit.CreateContext(modPara);
                InteractiveExecutor itrEx = new(llmContx);
                //チャットログを読み込みます。
                ChatHistory chtHis = new ChatHistory();
                chtDB = new ChatHistoryDB(strChatlogPath, chtHis, strTable);
                ChatSession chtSess = new(itrEx, chtHis);
                var varHidewd = new LLamaTransforms.KeywordTextOutputStreamTransform(["User: ", "Assistant: "]);
                chtSess.WithOutputTransform(varHidewd);
                InferenceParams infPara = new()
                {
                    SamplingPipeline = new DefaultSamplingPipeline()
                    {
                        Temperature = App.Default.tmp,
                        Seed = 1337,
                    },
                    AntiPrompts = ["User:"],
                    MaxTokens = 256,
                };
                //タイマー定義
                silenceTimer = new System.Timers.Timer(itrvl);
                //チャットロジック
                Func<string, Task> Chat = async (string strUserInput) =>
                {
                    if (!Wt)
                    {
                        Wt = true;
                        ChatHistory.Message msgText = new(AuthorRole.User, strUserInput);
                        Console.ForegroundColor = ConsoleColor.White;
                        if (msg) Console.WriteLine("User: " + strUserInput);
                        if (Op) chtDB.WriteHistory(AuthorRole.User, "User: "+ strUserInput);
                        // 回答の表示
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        string strMsg = "";
                        await foreach (string strText in chtSess.ChatAsync(msgText, infPara)) strMsg += strText;
                        //発信するときは「User:」や「Assistant:」を抜く
                        string strSndmsg = strMsg.Replace("User:", "").Replace("Assistant:", "").Replace("assistant:", "").Trim();
                        if (msg) Console.WriteLine("Assistant: " + strSndmsg);
                        if (Op) chtDB.WriteHistory(AuthorRole.Assistant, strMsg);
                        //音声ソフト実行
                        SpeechSynthesis(strSndmsg);
                        Wt = false;
                    }
                };
                // SpeechRecognitionの設定
                //AI会話設定とイベント定義
                SpeechRecognizer recognizer = new SpeechRecognizer();
                // Set timeout settings.
                recognizer.Timeouts.InitialSilenceTimeout = TimeSpan.FromSeconds(6.0); // (認識結果が生成されるまでの) 無音を検出し、音声入力が続かないと見なす時間の長さ。
                recognizer.Timeouts.BabbleTimeout = TimeSpan.FromSeconds(4.0);         //認識できないサウンド (雑音) のリッスンを継続し、音声入力が終了したと見なし、認識処理を終了するまでの時間の長さ。
                recognizer.Timeouts.EndSilenceTimeout = TimeSpan.FromSeconds(1.2);     //(認識結果が生成された後の) 無音を検出し、音声入力が終了したと見なす時間の長さ。
                await recognizer.CompileConstraintsAsync();
                recognizer.ContinuousRecognitionSession.ResultGenerated += async (sender, e) =>
                {
                    //AI会話
                    if (!Wt)
                    {
                        silenceTimerCnt = 0;
                        silenceTimer.Stop();
                        await Chat(e.Result.Text.Replace("MK", "マンコ").Replace("TK", "チンコ").Replace("TP", "チンポ"));
                        silenceTimer.Start();
                    }
                    //Awake設定とイベント定義
                    bool Aw = false;
                    for (int i = 0; i < AwakeWord.Length; i++) if (Regex.IsMatch(e.Result.Text, $"^*{AwakeWord[i]}*$", RegexOptions.Singleline)) Aw = true;
                    if (Aw)
                    {
                        if (msg) Console.WriteLine($"{e.Result.Text}と言われました");
                        Wt = false;
                        //AIから話しかける
                        await Chat("(_ _)");
                        silenceTimerCnt = 0;
                        silenceTimer.Stop();
                        silenceTimer.Start();
                    }
                    //Asleep設定とイベント定義
                    bool Ap = false;
                    for (int i = 0; i < AsleepWord.Length; i++) if (Regex.IsMatch(e.Result.Text, $"^*{AsleepWord[i]}*$", RegexOptions.Singleline)) Ap = true;
                    if (Ap)
                    {
                        if (msg) Console.WriteLine($"{e.Result.Text}と言われました");
                        Wt = true;
                        silenceTimerCnt = 0;
                        silenceTimer.Stop();
                    }
                };
                //タイマーイベント定義
                silenceTimer.Elapsed  += async (sender, e) =>
                {
                    silenceTimerCnt++;
                    //AIから話しかける仕組み
                    if (silenceTimerCnt == 3)
                    {
                        Random rTalk = new Random();
                        if (rTalk.Next(0, 1) == 0) //乱数で0が出たら話しかける。トリガーは"??"
                        {
                            await Chat("??");
                        }
                    }
                    if (silenceTimerCnt >= silenceTimerMax)
                    {
                        Wt = true;
                        if (msg) Console.WriteLine("休止しました。");
                        silenceTimerCnt = 0;
                        silenceTimer.Stop();
                    }
                    else
                    {
                        if (recognizer.State == SpeechRecognizerState.Idle)
                        {
                            await recognizer.ContinuousRecognitionSession.StartAsync();
                        }
                    }
                };
                //AI会話タイムアウト
                recognizer.ContinuousRecognitionSession.Completed += async (sender, e) =>
                {
                    // Recognizer Restart
                    await recognizer.ContinuousRecognitionSession.StartAsync();
                };
                // Recognizer Start  
                await recognizer.ContinuousRecognitionSession.StartAsync();
                Console.WriteLine("★★ マイクに向かって話してください ★★");
                // Keep the console window open.  
                while (true)
                {
                    Console.ReadLine();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
        private static void SpeechSynthesis(string strMsg)
        {
            //音声ソフト選択
            if (App.Default.SpeechSynth==1) CevioAI(strMsg);
            if (App.Default.SpeechSynth==2)
            {
                if (Process.GetProcessesByName("VOICEVOX").Length == 0)
                {
                    var vx = new ProcessStartInfo();
                    vx.FileName = Environment.GetEnvironmentVariable("VOICEVOX_PATH", System.EnvironmentVariableTarget.User);
                    vx.UseShellExecute = true;
                    Process.Start(vx);
                    Thread.Sleep(2000);
                }
                Task task = Voicevox(strMsg);
                task.Wait();
            }
        }
        private static void CevioAI(string strMsg)
        {
            try
            {
                dynamic service = Activator.CreateInstance(Type.GetTypeFromProgID("CeVIO.Talk.RemoteService2.ServiceControl2V40"));
                service.StartHost(false);
                dynamic talker = Activator.CreateInstance(Type.GetTypeFromProgID("CeVIO.Talk.RemoteService2.Talker2V40"));
                talker.Cast = App.Default.CEVIOAI_CAST;
                dynamic result = talker.Speak(strMsg);
                result.Wait();
                //開放忘れるとメモリリーク
                System.Runtime.InteropServices.Marshal.ReleaseComObject(talker);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(service);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
        private static async Task Voicevox(string strMsg)
        {
            MemoryStream? ms;
            try
            {
                using (var httpClient = new HttpClient())
                {
                    string strQuery;
                    // 音声クエリを生成
                    using (var varRequest = new HttpRequestMessage(new HttpMethod("POST"), $"http://127.0.0.1:{App.Default.VOICEVOX_PORT}/audio_query?text={strMsg}&speaker={App.Default.VOICEVOX_SPEAKER}&speedScale=1.5&prePhonemeLength=0&postPhonemeLength=0&intonationScale=1.16&enable_interrogative_upspeak=true"))
                    {
                        varRequest.Headers.TryAddWithoutValidation("accept", "application/json");
                        varRequest.Content = new StringContent("");
                        varRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
                        var response = await httpClient.SendAsync(varRequest);
                        strQuery = response.Content.ReadAsStringAsync().Result;
                    }

                    // 音声クエリから音声合成
                    using (var request = new HttpRequestMessage(new HttpMethod("POST"), $"http://127.0.0.1:{App.Default.VOICEVOX_PORT}/synthesis?speaker={App.Default.VOICEVOX_SPEAKER}&enable_interrogative_upspeak=true&speedScale=1.5&prePhonemeLength=0&postPhonemeLength=0&intonationScale=1.16"))
                    {
                        request.Headers.TryAddWithoutValidation("accept", "audio/wav");
                        request.Content = new StringContent(strQuery);
                        request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
                        var response = await httpClient.SendAsync(request);
                        // 音声を保存
                        using (ms = new MemoryStream())
                        {
                            using (var httpStream = await response.Content.ReadAsStreamAsync())
                            {
                                httpStream.CopyTo(ms);
                                ms.Flush();
                            }
                        }
                    }
                }
                ms = new MemoryStream(ms.ToArray());
                //読み込む
                var player = new SoundPlayer(ms);
                //再生する
                player.PlaySync();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}




ChatHistoryDB.cs SQLiteでチャット履歴を管理
1.7からの修正点
・なし

using LLama.Common;
using System.Data.SQLite;
using HtmlAgilityPack;

namespace AI_Chat
{
    class ChatHistoryDB
    {
        ChatHistory? chtHis;
        string strDbpath;
        Dictionary<string, AuthorRole>? Roles = new Dictionary<string, AuthorRole> { { "System", AuthorRole.System }, { "User", AuthorRole.User }, { "Assistant", AuthorRole.Assistant } };
        string strTable;

        public ChatHistoryDB(string strDbpath, ChatHistory chtHis, string strTable)
        {

            this.chtHis= chtHis;
            this.strDbpath= strDbpath;
            this.strTable= strTable;

            try
            {
                var conSb = new SQLiteConnectionStringBuilder { DataSource = strDbpath };

                var con = new SQLiteConnection(conSb.ToString());
                con.Open();

                using (var cmd = new SQLiteCommand(con))
                {
                    cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {strTable}(" +
                        "\"sq\"  INTEGER," +
                        "\"dt\"  TEXT NOT NULL," +
                        "\"id\"  TEXT NOT NULL," +
                        "\"msg\" TEXT," +
                        "\"flg\" INTEGER DEFAULT 0, PRIMARY KEY(\"sq\"))";
                    cmd.ExecuteNonQuery();

                    cmd.CommandText = $"select count(*)  from {strTable}";
                    using (var reader = cmd.ExecuteReader())
                    {
                        //一行も存在しない場合はシステム行をセットアップ
                        long reccount = 0;
                        if (reader.Read()) reccount = (long)reader[0];
                        reader.Close();
                        if (reccount<1)
                        {
                            //Assistantの性格セットアップ行追加
                            cmd.CommandText = $"insert into {strTable}(dt,id,msg) values(datetime('now', 'localtime'),'System','あなたは優秀なアシスタントです。')";
                            cmd.ExecuteNonQuery();
                            //要約行追加
                            cmd.CommandText = $"insert into {strTable}(dt,id,msg) values(datetime('now', 'localtime'),'System','')";
                            //最新情報行追加
                            cmd.CommandText = $"insert into {strTable}(dt,id,msg) values(datetime('now', 'localtime'),'System','')";
                            cmd.ExecuteNonQuery();
                        }
                    }
                    //最新情報を更新
                    cmd.CommandText = $"update {strTable} set dt=datetime('now', 'localtime'),msg='今日は、{DateTime.Now.ToString("yyyy年M月d日dddd")}です。\n" + 
                                       GetWether().Result + "\n" + GetNikkeiStkAvg().Result + "' where sq=3";
                    cmd.ExecuteNonQuery();

                    //システム行を履歴に読み込む"
                    string strMsg = "";
                    cmd.CommandText = $"select * from {strTable} where id='System' order by sq";
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            strMsg += (string)reader["msg"] + "\n";
                        }
                    }
                    if (chtHis is null) chtHis=new ChatHistory();
                    chtHis.AddMessage(AuthorRole.System,strMsg);

                    //会話行を履歴に読み込む
                    cmd.CommandText = $"select * from {strTable} where flg=0 and id<>'System' order by sq";
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            chtHis.AddMessage(Roles[(string)reader["id"]], (string)reader["msg"]);
                        }
                    }
                }

                con.Close();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        public interface IDisposable
        {
            void Dispose();
        }


        public void WriteHistory(AuthorRole aurID, string strMsg, bool booHis = false)
        {
            try
            {
                var conSb = new SQLiteConnectionStringBuilder { DataSource = strDbpath };

                var con = new SQLiteConnection(conSb.ToString());
                con.Open();

                using (var cmd = new SQLiteCommand(con))
                {
                    if (booHis)
                    {
                        if (chtHis is null) chtHis=new ChatHistory();
                        chtHis.AddMessage(aurID, strMsg);
                    }
                    cmd.CommandText = $"insert into {strTable}(dt,id,msg) values(datetime('now', 'localtime'),'{Roles.FirstOrDefault(v => v.Value.Equals(aurID)).Key}','{strMsg}')";
                    cmd.ExecuteNonQuery();
                }
                con.Close();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private static async Task<string> GetNikkeiStkAvg()
        {
            // 株価取得 
            HttpClient webClient = new HttpClient();
            string page = await webClient.GetStringAsync("https://www.nikkei.com/markets/worldidx/chart/nk225/");

            var htmlDocument = new HtmlDocument();
            htmlDocument.LoadHtml(page);

            // Select nodes using XPath 
            var node = htmlDocument.DocumentNode.SelectSingleNode("//span[@class=\"economic_value_now a-fs26\"]");

            // Extract and display data
            string txtcontents = "日経平均株価は、不明です。";
            if (node is not null) txtcontents = $"日経平均株価は、{node.InnerText.Trim()}円です。";
            node = htmlDocument.DocumentNode.SelectSingleNode("//span[@class=\"economic_value_time a-fs14\"]");
            if (node is not null) txtcontents += node.InnerText.Trim();
            //Console.WriteLine(txtcontents);
            return txtcontents;
        }

        private static async Task<string> GetWether()
        {
            // 天気予報 
            HttpClient webClient = new HttpClient();
            string page = await webClient.GetStringAsync("https://tenki.jp/");

            var htmlDocument = new HtmlDocument();
            htmlDocument.LoadHtml(page);

            // Select nodes using XPath 
            var nodes = htmlDocument.DocumentNode.SelectNodes("//div[@class=\"forecast-comment\"]");

            string txtcontents = "今日の天気は、不明です。";
            // Extract and display data
            if (nodes is not null)
            {
                txtcontents = "今日の天気は、「";
                foreach (var node in nodes)
                {
                    txtcontents += node.InnerText.Trim();
                }
                txtcontents += "」です。";
            }
            //Console.WriteLine(txtcontents);
            return txtcontents;
        }
    }
}




HistorySummary.cs 長くなった会話を要約して圧縮しSEQ=3のシステム行のmsgにぶちこむ。要約が終わった行は論理削除。
要約には「DataPilot-ArrowPro-7B-RobinHood」が優秀だったので使ってます。
1.7からの修正点
・なし

using LLama.Common;
using LLama;
using System.Data.SQLite;

namespace AI_Chat
{
    internal class HistorySummary
    {
        public static async Task Run(string strChatlogPath, uint HistoryMax, string strTable)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("**Start History Summary**");

            try
            {
                // LLMモデルの場所
                string strModelPath = Environment.GetEnvironmentVariable("LLMPATH", System.EnvironmentVariableTarget.User) + @"mmnga\DataPilot-ArrowPro-7B-RobinHood-gguf\DataPilot-ArrowPro-7B-RobinHood-Q8_0.gguf";
                // ChatDBから行を読み込む
                string strChtHis = "";
                uint i = 0;
                uint intCtxtSize = 4096; //一度に処理できる文字数
                long svSq = 0;    //処理を開始したSq
                long svSqMax = 0; //処理を終了したSq
                var conSb = new SQLiteConnectionStringBuilder { DataSource = strChatlogPath };
                var con = new SQLiteConnection(conSb.ToString());
                con.Open();
                using (var cmd = new SQLiteCommand(con))
                {
                    //有効文字数をカウント
                    cmd.CommandText = $"select sum(length(msg))  from {strTable} where flg=0";
                    using (var reader = cmd.ExecuteReader())
                    {
                        reader.Read();
                        //Console.WriteLine($"文字数:{reader[0]}");
                        //チャット履歴の最大行に満たないか、最大文字数を越えても処理できる文字数が充分でない場合は処理をしない
                        if ((long)reader[0] < (long)HistoryMax || (long)reader[0] - (long)HistoryMax < (long)intCtxtSize)
                        {
                            con.Close();
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.WriteLine("**E.N.D History Summary**");
                            return;
                        }
                    }
                    //有効行を呼んで要約する
                    cmd.CommandText = $"select * from {strTable} where flg=0 and sq>2 order by sq";
                    string strCht = "";
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            strCht = (string)reader["id"] + ": " + ((string)reader["msg"]).Replace("User:", "").Replace("Assistant:", "").Replace("assistant:", "").Trim() + "\n";
                            i += (uint)strCht.Length;
                            if (i > intCtxtSize) { break; }
                            strChtHis += strCht;
                            //システム行以外で処理を開始した行を記録
                            if ((string)reader["id"] != "System" && svSq == 0)
                            {
                                svSq = (long)reader["sq"];
                            }
                            svSqMax = (long)reader["sq"];
                        }
                    }
                }

                //LLMの処理
                Console.ForegroundColor = ConsoleColor.Blue;

                //LLMモデルのロードとパラメータの設定
                ModelParams modPara = new(strModelPath)
                {
                    ContextSize = intCtxtSize,
                    GpuLayerCount = 60
                };

                ChatHistory chtHis = new ChatHistory();
                chtHis.AddMessage(AuthorRole.System, "#命令書\n" +
                                                    "・あなたは優秀な編集者です。\n" +
                                                    "・ユーザーとアシスタントの会話を要約してください。\n" +
                                                    "#条件\n" +
                                                    "・重要なキーワードを取りこぼさない。\n" +
                                                    "#出力形式\n" +
                                                    "・例)要約: ふたりは親密な会話しました。");
                using LLamaWeights llmWeit = LLamaWeights.LoadFromFile(modPara);
                using LLamaContext llmContx = llmWeit.CreateContext(modPara);
                InteractiveExecutor itrEx = new(llmContx);
                ChatSession chtSess = new(itrEx, chtHis);
                var varHidewd = new LLamaTransforms.KeywordTextOutputStreamTransform(["User:", "Assistant:"]);
                chtSess.WithOutputTransform(varHidewd);
                InferenceParams infPara = new()
                {
                    Temperature = 0f,
                    AntiPrompts = new List<string> { "User:" }
                };

                // ユーザーのターン
                Console.ForegroundColor = ConsoleColor.White;
                string strInput =  strChtHis;
                ChatHistory.Message msg = new(AuthorRole.User, strInput);

                // AIのターン
                Console.ForegroundColor = ConsoleColor.Magenta;
                string strMsg = "";
                await foreach (string strAns in chtSess.ChatAsync(msg, infPara))
                {
                    Console.Write(strAns);
                    strMsg += strAns;
                }

                using (var cmd = new SQLiteCommand(con))
                {
                    //sq=1に要約内容を更新する(要約という文字、改行、空白を削除)
                    string strSql = $"update {strTable} set msg= '{strMsg.Replace("要約:", "").Replace("\r", "").Replace("\n", "").Trim()}' where sq=3";
                    //Console.Write (strSql+"\n");
                    cmd.CommandText = strSql;
                    cmd.ExecuteNonQuery();

                    //処理した行を論理削除する
                    strSql = $"update {strTable} set flg=1 where (sq between {svSq} and {svSqMax}) and id<>'System' and flg=0";
                    //Console.Write(strSql+"\n");
                    cmd.CommandText = strSql;
                    cmd.ExecuteNonQuery();
                }

                //DBクローズ
                con.Close();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("**E.N.D History Summary**");

        }
    }
}



ずっと立ち上げるならスケジューラで再起動すると要約が走るのでいいかも
PowerShellコマンドの参考例
AI_Server01.ps1

stop-process -Name "アプリのプロセス名"
Start-Sleep -Seconds 3
Start-Process -FilePath "アプリパス+EXE名"

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です