Compare commits
6 Commits
fenzu
...
feat/sendtool
| Author | SHA1 | Date | |
|---|---|---|---|
| 8faaa4b2be | |||
| 7f5bd942b3 | |||
| e254caf82d | |||
| 7efcd242d6 | |||
| 5d811d3949 | |||
| 8e6aaee10c |
@@ -234,7 +234,8 @@ pre-commit install
|
||||
- Group 7: 743746109
|
||||
- Group 8: 1030353265
|
||||
|
||||
- Developer Group: 975206796
|
||||
- Developer Group(Chit-chat): 975206796
|
||||
- Developer Group(Formal): 1039761811
|
||||
|
||||
### Discord Server
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ pre-commit install
|
||||
- Groupe 5 : 822130018
|
||||
- Groupe 6 : 753075035
|
||||
- Groupe développeurs : 975206796
|
||||
- Groupe développeurs (officiel) : 1039761811
|
||||
|
||||
### Serveur Discord
|
||||
|
||||
|
||||
@@ -223,6 +223,7 @@ pre-commit install
|
||||
- 5群: 822130018
|
||||
- 6群: 753075035
|
||||
- 開発者群: 975206796
|
||||
- 開発者群(正式): 1039761811
|
||||
|
||||
### Discord サーバー
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ pre-commit install
|
||||
- Группа 5: 822130018
|
||||
- Группа 6: 753075035
|
||||
- Группа разработчиков: 975206796
|
||||
- Группа разработчиков (официальная): 1039761811
|
||||
|
||||
### Сервер Discord
|
||||
|
||||
|
||||
+2
-1
@@ -225,7 +225,8 @@ pre-commit install
|
||||
- 6 群:753075035
|
||||
- 7 群:743746109
|
||||
- 8 群:1030353265
|
||||
- 開發者群:975206796
|
||||
- 開發者群(闲聊吹水):975206796
|
||||
- 開發者群(正式):1039761811
|
||||
|
||||
### Discord 群組
|
||||
|
||||
|
||||
+2
-1
@@ -226,7 +226,8 @@ pre-commit install
|
||||
- 6 群:753075035
|
||||
- 7 群:743746109
|
||||
- 8 群:1030353265
|
||||
- 开发者群:975206796
|
||||
- 开发者群(偏闲聊吹水):975206796
|
||||
- 开发者群(正式):1039761811
|
||||
|
||||
### Discord 频道
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ class SendMessageToUserTool(FunctionTool[AstrAgentContext]):
|
||||
"type": "string",
|
||||
"description": (
|
||||
"Component type. One of: "
|
||||
"plain, image, record, file, mention_user"
|
||||
"plain, image, record, video, file, mention_user. Record is voice message."
|
||||
),
|
||||
},
|
||||
"text": {
|
||||
@@ -320,6 +320,19 @@ class SendMessageToUserTool(FunctionTool[AstrAgentContext]):
|
||||
components.append(Comp.Record.fromURL(url=url))
|
||||
else:
|
||||
return f"error: messages[{idx}] must include path or url for record component."
|
||||
elif msg_type == "video":
|
||||
path = msg.get("path")
|
||||
url = msg.get("url")
|
||||
if path:
|
||||
(
|
||||
local_path,
|
||||
file_from_sandbox,
|
||||
) = await self._resolve_path_from_sandbox(context, path)
|
||||
components.append(Comp.Video.fromFileSystem(path=local_path))
|
||||
elif url:
|
||||
components.append(Comp.Video.fromURL(url=url))
|
||||
else:
|
||||
return f"error: messages[{idx}] must include path or url for video component."
|
||||
elif msg_type == "file":
|
||||
path = msg.get("path")
|
||||
url = msg.get("url")
|
||||
|
||||
@@ -422,6 +422,12 @@ async def get_booter(
|
||||
) -> ComputerBooter:
|
||||
config = context.get_config(umo=session_id)
|
||||
|
||||
runtime = config.get("provider_settings", {}).get("computer_use_runtime", "local")
|
||||
if runtime == "local":
|
||||
return get_local_booter()
|
||||
elif runtime == "none":
|
||||
raise RuntimeError("Sandbox runtime is disabled by configuration.")
|
||||
|
||||
sandbox_cfg = config.get("provider_settings", {}).get("sandbox", {})
|
||||
booter_type = sandbox_cfg.get("booter", "shipyard_neo")
|
||||
|
||||
|
||||
@@ -219,6 +219,9 @@ DEFAULT_CONFIG = {
|
||||
"telegram": {
|
||||
"pre_ack_emoji": {"enable": False, "emojis": ["✍️"]},
|
||||
},
|
||||
"discord": {
|
||||
"pre_ack_emoji": {"enable": False, "emojis": ["🤔"]},
|
||||
},
|
||||
},
|
||||
"wake_prefix": ["/"],
|
||||
"log_level": "INFO",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useModuleI18n } from '@/i18n/composables';
|
||||
import { normalizeTextInput } from '@/utils/inputValue';
|
||||
|
||||
const { tm } = useModuleI18n('features/command');
|
||||
|
||||
@@ -52,6 +53,7 @@ const statusItems = [
|
||||
{ title: tm('filters.disabled'), value: 'disabled' },
|
||||
{ title: tm('filters.conflict'), value: 'conflict' }
|
||||
];
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -108,10 +110,11 @@ const statusItems = [
|
||||
<div style="min-width: 200px; max-width: 350px; flex: 1; border: 1px solid #B9B9B9; border-radius: 16px;">
|
||||
<v-text-field
|
||||
:model-value="searchQuery"
|
||||
@update:model-value="emit('update:searchQuery', $event)"
|
||||
@update:model-value="emit('update:searchQuery', normalizeTextInput($event))"
|
||||
density="compact"
|
||||
:label="tm('search.placeholder')"
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
clearable
|
||||
variant="solo-filled"
|
||||
flat
|
||||
hide-details
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
import { ref, computed, type Ref } from 'vue';
|
||||
import type { CommandItem, FilterState } from '../types';
|
||||
import { normalizeTextInput } from '@/utils/inputValue';
|
||||
|
||||
export function useCommandFilters(commands: Ref<CommandItem[]>) {
|
||||
// 过滤状态
|
||||
@@ -95,7 +96,7 @@ export function useCommandFilters(commands: Ref<CommandItem[]>) {
|
||||
* 过滤后的指令列表(支持层级结构)
|
||||
*/
|
||||
const filteredCommands = computed(() => {
|
||||
const query = searchQuery.value.toLowerCase();
|
||||
const query = normalizeTextInput(searchQuery.value).toLowerCase();
|
||||
const conflictCmds: CommandItem[] = [];
|
||||
const normalCmds: CommandItem[] = [];
|
||||
|
||||
@@ -184,4 +185,3 @@ export function useCommandFilters(commands: Ref<CommandItem[]>) {
|
||||
isGroupExpanded
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import { computed, onActivated, onMounted, ref, watch} from 'vue';
|
||||
import axios from 'axios';
|
||||
import { useModuleI18n } from '@/i18n/composables';
|
||||
import { normalizeTextInput } from '@/utils/inputValue';
|
||||
|
||||
// Composables
|
||||
import { useComponentData } from './composables/useComponentData';
|
||||
@@ -83,7 +84,7 @@ const {
|
||||
} = useCommandActions(toast, () => fetchCommands(tm('messages.loadFailed')));
|
||||
|
||||
const filteredTools = computed(() => {
|
||||
const query = toolSearch.value.trim().toLowerCase();
|
||||
const query = normalizeTextInput(toolSearch.value).trim().toLowerCase();
|
||||
if (!query) return tools.value;
|
||||
return tools.value.filter(tool =>
|
||||
tool.name?.toLowerCase().includes(query) ||
|
||||
@@ -253,7 +254,8 @@ watch(viewMode, async (mode) => {
|
||||
<div class="d-flex flex-wrap align-center ga-3 mb-4">
|
||||
<div style="min-width: 240px; max-width: 380px; flex: 1;">
|
||||
<v-text-field
|
||||
v-model="toolSearch"
|
||||
:model-value="toolSearch"
|
||||
@update:model-value="toolSearch = normalizeTextInput($event)"
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
:label="tmTool('functionTools.search')"
|
||||
variant="outlined"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
v-model="modelSearchProxy"
|
||||
density="compact"
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
clearable
|
||||
hide-details
|
||||
variant="solo-filled"
|
||||
flat
|
||||
@@ -161,6 +162,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { normalizeTextInput } from '@/utils/inputValue'
|
||||
|
||||
const props = defineProps({
|
||||
entries: {
|
||||
@@ -222,7 +224,7 @@ const emit = defineEmits([
|
||||
|
||||
const modelSearchProxy = computed({
|
||||
get: () => props.modelSearch,
|
||||
set: (val) => emit('update:modelSearch', val)
|
||||
set: (val) => emit('update:modelSearch', normalizeTextInput(val))
|
||||
})
|
||||
|
||||
const isProviderTesting = (providerId) => props.testingProviders.includes(providerId)
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ref, computed, onMounted, nextTick, watch } from 'vue'
|
||||
import axios from 'axios'
|
||||
import { getProviderIcon } from '@/utils/providerUtils'
|
||||
import { askForConfirmation as askForConfirmationDialog, useConfirmDialog } from '@/utils/confirmDialog'
|
||||
import { normalizeTextInput } from '@/utils/inputValue'
|
||||
|
||||
export interface UseProviderSourcesOptions {
|
||||
defaultTab?: string
|
||||
@@ -157,7 +158,7 @@ export function useProviderSources(options: UseProviderSourcesOptions) {
|
||||
})
|
||||
|
||||
const filteredMergedModelEntries = computed(() => {
|
||||
const term = modelSearch.value.trim().toLowerCase()
|
||||
const term = normalizeTextInput(modelSearch.value).trim().toLowerCase()
|
||||
if (!term) return mergedModelEntries.value
|
||||
|
||||
return mergedModelEntries.value.filter((entry: any) => {
|
||||
|
||||
@@ -873,7 +873,8 @@
|
||||
]
|
||||
},
|
||||
"regex": {
|
||||
"description": "Segmentation Regular Expression"
|
||||
"description": "Segmentation Regular Expression",
|
||||
"hint": "Used to identify split points with a regular expression. Prefer patterns that match separators."
|
||||
},
|
||||
"split_words": {
|
||||
"description": "Split Word List",
|
||||
|
||||
@@ -876,7 +876,8 @@
|
||||
]
|
||||
},
|
||||
"regex": {
|
||||
"description": "分段正则表达式"
|
||||
"description": "分段正则表达式",
|
||||
"hint": "用于按正则规则识别分段点。建议使用能匹配分隔符的表达式。"
|
||||
},
|
||||
"split_words": {
|
||||
"description": "分段词列表",
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export const normalizeTextInput = (value: unknown): string =>
|
||||
typeof value === 'string' ? value : '';
|
||||
@@ -13,9 +13,11 @@
|
||||
</v-select>
|
||||
<v-text-field
|
||||
class="config-search-input"
|
||||
v-model="configSearchKeyword"
|
||||
:model-value="configSearchKeyword"
|
||||
@update:model-value="onConfigSearchInput"
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
:label="tm('search.placeholder')"
|
||||
clearable
|
||||
hide-details
|
||||
density="compact"
|
||||
rounded="md"
|
||||
@@ -211,6 +213,7 @@ import {
|
||||
useConfirmDialog
|
||||
} from '@/utils/confirmDialog';
|
||||
import UnsavedChangesConfirmDialog from '@/components/config/UnsavedChangesConfirmDialog.vue';
|
||||
import { normalizeTextInput } from '@/utils/inputValue';
|
||||
|
||||
export default {
|
||||
name: 'ConfigPage',
|
||||
@@ -419,6 +422,9 @@ export default {
|
||||
|
||||
},
|
||||
methods: {
|
||||
onConfigSearchInput(value) {
|
||||
this.configSearchKeyword = normalizeTextInput(value);
|
||||
},
|
||||
extractConfigTypeFromHash(hash) {
|
||||
const rawHash = String(hash || '');
|
||||
const lastHashIndex = rawHash.lastIndexOf('#');
|
||||
|
||||
@@ -353,10 +353,11 @@
|
||||
<v-window-item value="search">
|
||||
<div class="search-container pa-4">
|
||||
<v-form @submit.prevent="searchKnowledgeBase" class="d-flex align-center">
|
||||
<v-text-field v-model="searchQuery" :label="tm('search.queryLabel')"
|
||||
<v-text-field :model-value="searchQuery"
|
||||
@update:model-value="onSearchQueryInput" :label="tm('search.queryLabel')"
|
||||
append-icon="mdi-magnify" variant="outlined" class="flex-grow-1 me-2"
|
||||
@click:append="searchKnowledgeBase" @keyup.enter="searchKnowledgeBase"
|
||||
:placeholder="tm('search.queryPlaceholder')" hide-details></v-text-field>
|
||||
:placeholder="tm('search.queryPlaceholder')" hide-details clearable></v-text-field>
|
||||
|
||||
<v-select v-model="topK" :items="[3, 5, 10, 20]"
|
||||
:label="tm('search.resultCountLabel')" variant="outlined"
|
||||
@@ -434,6 +435,7 @@
|
||||
import axios from 'axios';
|
||||
import ConsoleDisplayer from '@/components/shared/ConsoleDisplayer.vue';
|
||||
import { useModuleI18n } from '@/i18n/composables';
|
||||
import { normalizeTextInput } from '@/utils/inputValue';
|
||||
|
||||
export default {
|
||||
name: 'KnowledgeBase',
|
||||
@@ -580,6 +582,9 @@ export default {
|
||||
this.getProviderList();
|
||||
},
|
||||
methods: {
|
||||
onSearchQueryInput(value) {
|
||||
this.searchQuery = normalizeTextInput(value);
|
||||
},
|
||||
getSelectedGitHubProxy() {
|
||||
if (typeof window === "undefined" || !window.localStorage) return "";
|
||||
return localStorage.getItem("githubProxyRadioValue") === "1"
|
||||
@@ -903,7 +908,8 @@ export default {
|
||||
},
|
||||
|
||||
searchKnowledgeBase() {
|
||||
if (!this.searchQuery.trim()) {
|
||||
const query = normalizeTextInput(this.searchQuery).trim();
|
||||
if (!query) {
|
||||
this.showSnackbar(this.tm('messages.pleaseEnterSearchContent'), 'warning');
|
||||
return;
|
||||
}
|
||||
@@ -914,7 +920,7 @@ export default {
|
||||
axios.get(`/api/plug/alkaid/kb/collection/search`, {
|
||||
params: {
|
||||
collection_name: this.currentKB.collection_name,
|
||||
query: this.searchQuery,
|
||||
query,
|
||||
top_k: this.topK
|
||||
}
|
||||
})
|
||||
|
||||
@@ -37,10 +37,12 @@
|
||||
<h3>{{ tm('search.title') }}</h3>
|
||||
<v-card variant="outlined" class="mt-2 pa-3">
|
||||
<div>
|
||||
<v-text-field v-model="searchMemoryUserId" :label="tm('search.userIdLabel')" variant="outlined" density="compact" hide-details
|
||||
class="mb-2"></v-text-field>
|
||||
<v-text-field v-model="searchQuery" :label="tm('search.queryLabel')" variant="outlined" density="compact" hide-details
|
||||
@keyup.enter="searchMemory" class="mb-2"></v-text-field>
|
||||
<v-text-field :model-value="searchMemoryUserId"
|
||||
@update:model-value="onSearchMemoryUserIdInput" :label="tm('search.userIdLabel')" variant="outlined" density="compact" hide-details
|
||||
class="mb-2" clearable></v-text-field>
|
||||
<v-text-field :model-value="searchQuery"
|
||||
@update:model-value="onSearchQueryInput" :label="tm('search.queryLabel')" variant="outlined" density="compact" hide-details
|
||||
@keyup.enter="searchMemory" class="mb-2" clearable></v-text-field>
|
||||
<v-btn color="info" @click="searchMemory" :loading="isSearching" variant="tonal">
|
||||
<v-icon start>mdi-text-search</v-icon>
|
||||
{{ tm('search.searchButton') }}
|
||||
@@ -254,6 +256,7 @@
|
||||
import axios from 'axios';
|
||||
// import * as d3 from "d3"; // npm install d3
|
||||
import { useModuleI18n } from '@/i18n/composables';
|
||||
import { normalizeTextInput } from '@/utils/inputValue';
|
||||
|
||||
export default {
|
||||
name: 'LongTermMemory',
|
||||
@@ -336,9 +339,16 @@ export default {
|
||||
this.searchResults = [];
|
||||
},
|
||||
methods: {
|
||||
onSearchMemoryUserIdInput(value) {
|
||||
this.searchMemoryUserId = normalizeTextInput(value);
|
||||
},
|
||||
onSearchQueryInput(value) {
|
||||
this.searchQuery = normalizeTextInput(value);
|
||||
},
|
||||
// 添加搜索记忆方法
|
||||
searchMemory() {
|
||||
if (!this.searchQuery.trim()) {
|
||||
const query = normalizeTextInput(this.searchQuery).trim();
|
||||
if (!query) {
|
||||
this.$toast.warning(this.tm('messages.searchQueryRequired'));
|
||||
return;
|
||||
}
|
||||
@@ -349,12 +359,13 @@ export default {
|
||||
|
||||
// 构建查询参数
|
||||
const params = {
|
||||
query: this.searchQuery
|
||||
query
|
||||
};
|
||||
|
||||
// 如果有选择用户ID,也加入查询参数
|
||||
if (this.searchMemoryUserId) {
|
||||
params.user_id = this.searchMemoryUserId;
|
||||
const normalizedUserId = normalizeTextInput(this.searchMemoryUserId).trim();
|
||||
if (normalizedUserId) {
|
||||
params.user_id = normalizedUserId;
|
||||
}
|
||||
|
||||
axios.get('/api/plug/alkaid/ltm/graph/search', { params })
|
||||
|
||||
@@ -3,6 +3,7 @@ import PluginSortControl from "@/components/extension/PluginSortControl.vue";
|
||||
import ExtensionCard from "@/components/shared/ExtensionCard.vue";
|
||||
import StyledMenu from "@/components/shared/StyledMenu.vue";
|
||||
import defaultPluginIcon from "@/assets/images/plugin_icon.png";
|
||||
import { normalizeTextInput } from "@/utils/inputValue";
|
||||
|
||||
const props = defineProps({
|
||||
state: {
|
||||
@@ -164,10 +165,12 @@ const {
|
||||
|
||||
<div class="d-flex align-center flex-wrap ml-auto" style="gap: 8px">
|
||||
<v-text-field
|
||||
v-model="pluginSearch"
|
||||
:model-value="pluginSearch"
|
||||
@update:model-value="pluginSearch = normalizeTextInput($event)"
|
||||
density="compact"
|
||||
:label="tm('search.placeholder')"
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
clearable
|
||||
variant="solo-filled"
|
||||
flat
|
||||
hide-details
|
||||
|
||||
@@ -3,6 +3,7 @@ import MarketPluginCard from "@/components/extension/MarketPluginCard.vue";
|
||||
import PluginSortControl from "@/components/extension/PluginSortControl.vue";
|
||||
import defaultPluginIcon from "@/assets/images/plugin_icon.png";
|
||||
import { computed } from "vue";
|
||||
import { normalizeTextInput } from "@/utils/inputValue";
|
||||
|
||||
const props = defineProps({
|
||||
state: {
|
||||
@@ -212,11 +213,13 @@ const marketSortItems = computed(() => [
|
||||
</div>
|
||||
|
||||
<v-text-field
|
||||
v-model="marketSearch"
|
||||
:model-value="marketSearch"
|
||||
@update:model-value="marketSearch = normalizeTextInput($event)"
|
||||
class="ml-auto"
|
||||
density="compact"
|
||||
:label="tm('search.marketPlaceholder')"
|
||||
prepend-inner-icon="mdi-magnify"
|
||||
clearable
|
||||
variant="solo-filled"
|
||||
flat
|
||||
hide-details
|
||||
|
||||
@@ -245,7 +245,7 @@ export default defineConfig({
|
||||
next: '下一篇'
|
||||
},
|
||||
editLink: {
|
||||
pattern: 'https://github.com/AstrBotdevs/AstrBot-docs/edit/v4/:path',
|
||||
pattern: 'https://github.com/AstrBotdevs/AstrBot/edit/master/docs/:path',
|
||||
text: '发现文档有问题?在 GitHub 上编辑此页',
|
||||
},
|
||||
logo: '/logo_prod.png',
|
||||
@@ -484,7 +484,7 @@ export default defineConfig({
|
||||
next: 'Next'
|
||||
},
|
||||
editLink: {
|
||||
pattern: 'https://github.com/AstrBotdevs/AstrBot-docs/edit/v4/:path',
|
||||
pattern: 'https://github.com/AstrBotdevs/AstrBot/edit/master/docs/:path',
|
||||
text: 'Edit this page on GitHub',
|
||||
},
|
||||
logo: '/logo_prod.png',
|
||||
|
||||
@@ -14,8 +14,6 @@ Welcome to submit Issues or Pull Requests:
|
||||
|
||||
- [AstrBotDevs/AstrBot](https://github.com/AstrBotDevs/AstrBot)
|
||||
|
||||
- [AstrBotDevs/AstrBot-Docs](https://github.com/AstrBotDevs/AstrBot-docs)
|
||||
|
||||
### Tencent QQ Groups
|
||||
|
||||
> - All groups are available to join. If you find that the group size is below the limit, please feel free to join.
|
||||
|
||||
@@ -128,6 +128,9 @@ The default AstrBot configuration is as follows:
|
||||
"telegram": {
|
||||
"pre_ack_emoji": {"enable": False, "emojis": ["✍️"]},
|
||||
},
|
||||
"discord": {
|
||||
"pre_ack_emoji": {"enable": False, "emojis": ["🤔"]},
|
||||
},
|
||||
},
|
||||
"wake_prefix": ["/"],
|
||||
"log_level": "INFO",
|
||||
@@ -511,6 +514,11 @@ When enabled, AstrBot sends a pre-reply emoji before requesting the LLM to infor
|
||||
- `enable`: Whether to enable pre-reply emojis for Telegram messages. Default is `false`.
|
||||
- `emojis`: List of pre-reply emojis. Default is `["✍️"]`. Telegram only supports a fixed set of reactions; refer to [reactions.txt](https://gist.github.com/Soulter/3f22c8e5f9c7e152e967e8bc28c97fc9).
|
||||
|
||||
##### discord
|
||||
|
||||
- `enable`: Whether to enable pre-reply emojis for Discord messages. Default is `false`.
|
||||
- `emojis`: List of pre-reply emojis. Default is `["🤔"]`. Refer to [Discord Reaction FAQ](https://support.discord.com/hc/en-us/articles/12102061808663-Reactions-and-Super-Reactions-FAQ).
|
||||
|
||||
### `wake_prefix`
|
||||
|
||||
Wake prefix. Default is `/`. When a message starts with `/`, AstrBot is awakened.
|
||||
|
||||
@@ -29,8 +29,6 @@ https://discord.gg/PxgzhmxJ
|
||||
|
||||
- [AstrBotDevs/AstrBot](https://github.com/AstrBotDevs/AstrBot)
|
||||
|
||||
- [AstrBotDevs/AstrBot-Docs](https://github.com/AstrBotDevs/AstrBot-docs)
|
||||
|
||||
## 成为 AstrBot 组织成员
|
||||
|
||||
欢迎加入我们!
|
||||
|
||||
@@ -128,6 +128,9 @@ AstrBot 默认配置如下:
|
||||
"telegram": {
|
||||
"pre_ack_emoji": {"enable": False, "emojis": ["✍️"]},
|
||||
},
|
||||
"discord": {
|
||||
"pre_ack_emoji": {"enable": False, "emojis": ["🤔"]},
|
||||
},
|
||||
},
|
||||
"wake_prefix": ["/"],
|
||||
"log_level": "INFO",
|
||||
@@ -506,11 +509,16 @@ AstrBot WebUI 配置。
|
||||
- `enable`: 是否启用飞书消息预回复表情。默认为 `false`。
|
||||
- `emojis`: 预回复的表情列表。默认为 `["Typing"]`。表情枚举名参考:[表情文案说明](https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce)
|
||||
|
||||
#### telegram
|
||||
##### telegram
|
||||
|
||||
- `enable`: 是否启用 Telegram 消息预回复表情。默认为 `false`。
|
||||
- `emojis`: 预回复的表情列表。默认为 `["✍️"]`。Telegram 仅支持固定反应集合,参考:[reactions.txt](https://gist.github.com/Soulter/3f22c8e5f9c7e152e967e8bc28c97fc9)
|
||||
|
||||
##### discord
|
||||
|
||||
- `enable`: 是否启用 Discord 消息预回复表情。默认为 `false`。
|
||||
- `emojis`: 预回复的表情列表。默认为 `["🤔"]`。Discord反应支持参考:[Discord Reaction FAQ](https://support.discord.com/hc/en-us/articles/12102061808663-Reactions-and-Super-Reactions-FAQ)
|
||||
|
||||
### `wake_prefix`
|
||||
|
||||
唤醒前缀。默认为 `/`。当消息以 `/` 开头时,AstrBot 会被唤醒。
|
||||
|
||||
Reference in New Issue
Block a user