Add system memory monitoring, Bedrock support, and Discord integrations

- Add CPU/GPU memory monitoring endpoint and frontend widget
- Add Amazon Bedrock model support (API key / inference profiles) plus model selector entries
- Add Discord weather/laundry notification job (JMA forecast + LLM-generated message)
- Add Discord bot that replies to mentions via the configured LLM, with weather-aware context
- Add scheduled "useless tips" job with separate webhook and quiet-hours skip
- Switch FastAPI startup to lifespan handler, log viewer, markdown rendering, and toast UI additions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 00:59:38 +09:00
co-authored by Claude Sonnet 4.6
parent 903d34761c
commit 4a08ba29fa
34 changed files with 5051 additions and 160 deletions
+18 -7
View File
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref, watch, nextTick } from 'vue'
import { useChatStore } from '../stores/chat'
import MarkdownContent from './MarkdownContent.vue'
const store = useChatStore()
const scrollEl = ref<HTMLElement | null>(null)
@@ -22,11 +23,17 @@ watch(
<div
v-for="(msg, i) in store.messages"
:key="i"
:class="['message', msg.role, { pending: msg.pending }]"
:class="['message', msg.role, { error: msg.error }]"
>
<div class="bubble">
<span class="content">{{ msg.content }}</span>
<span v-if="msg.pending" class="cursor">▌</span>
<!-- ユーザーメッセージはプレーンテキスト -->
<template v-if="msg.role === 'user'">{{ msg.content }}</template>
<!-- アシスタントはMarkdownレンダリング -->
<template v-else>
<MarkdownContent :content="msg.content" :pending="msg.pending" />
<span v-if="msg.pending && !msg.content" class="cursor">▌</span>
</template>
</div>
</div>
</div>
@@ -46,9 +53,7 @@ watch(
color: #555;
font-size: 14px;
}
.message {
display: flex;
}
.message { display: flex; }
.message.user { justify-content: flex-end; }
.message.assistant { justify-content: flex-start; }
.bubble {
@@ -57,20 +62,26 @@ watch(
border-radius: 12px;
font-size: 14px;
line-height: 1.6;
white-space: pre-wrap;
word-break: break-word;
}
.user .bubble {
background: #2563eb;
color: #fff;
border-bottom-right-radius: 4px;
white-space: pre-wrap;
}
.assistant .bubble {
background: #2a2a2a;
color: #eee;
border-bottom-left-radius: 4px;
}
.message.error .bubble {
background: #3b1a1a;
color: #f87171;
border: 1px solid #7f1d1d;
}
.cursor {
display: inline-block;
animation: blink 0.8s step-end infinite;
}
@keyframes blink { 50% { opacity: 0; } }