Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## v3.6.4 可选系统信息注入与版本同步

本版本新增默认关闭的系统信息 Prompt 注入能力,并完成 3.6.4 版本号同步。

- 新增 `[prompt.system_info]`:可按 OS、Runtime、主机名、CPU、内存、Swap、磁盘、网络、进程和 uptime 控制展示,采集失败时跳过单项,不影响 Prompt 构建。
- 同步配置模板、配置文档、Prompt 顺序说明和回归测试。

---

## v3.6.3 合并转发快照、附件 UID 分析与 Release 下载说明

本版本聚焦合并转发在协议端不可二次读取时的可用性:收到消息时先把可访问的转发树按会话保存为本地快照,后续工具读取优先复用快照,避免内层转发过期或回源失败导致 AI 看不到内容。同时补齐文件分析 Agent 对内部附件 UID 的直接解析能力,并澄清 Release 产物的下载选择。
Expand Down
4 changes: 2 additions & 2 deletions apps/undefined-chat/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/undefined-chat/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "undefined-chat",
"private": true,
"version": "3.6.3",
"version": "3.6.4",
"type": "module",
"scripts": {
"tauri": "tauri",
Expand Down
2 changes: 1 addition & 1 deletion apps/undefined-chat/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/undefined-chat/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "undefined_chat"
version = "3.6.3"
version = "3.6.4"
description = "Undefined native chat client"
authors = ["Undefined contributors"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion apps/undefined-chat/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Undefined Chat",
"version": "3.6.3",
"version": "3.6.4",
"identifier": "com.undefined.chat",
"build": {
"beforeDevCommand": "npm run dev",
Expand Down
4 changes: 2 additions & 2 deletions apps/undefined-console/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/undefined-console/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "undefined-console",
"private": true,
"version": "3.6.3",
"version": "3.6.4",
"type": "module",
"scripts": {
"tauri": "tauri",
Expand Down
2 changes: 1 addition & 1 deletion apps/undefined-console/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/undefined-console/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "undefined_console"
version = "3.6.3"
version = "3.6.4"
description = "Undefined cross-platform management console"
authors = ["Undefined contributors"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion apps/undefined-console/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Undefined Console",
"version": "3.6.3",
"version": "3.6.4",
"identifier": "com.undefined.console",
"build": {
"beforeDevCommand": "npm run dev",
Expand Down
40 changes: 40 additions & 0 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,46 @@ prefetch_tools = ["get_current_time"]
# zh: 隐藏已预取的工具声明。
# en: Hide prefetched tools from the model's tool list.
prefetch_tools_hide = true

# zh: Prompt 系统信息注入。总开关默认关闭;开启后各子项默认展示,可逐项关闭。
# en: Prompt system information injection. The master switch is disabled by default; enabled sub-items are shown by default and can be disabled individually.
[prompt.system_info]
# zh: 是否把当前运行主机的系统信息注入提示词。默认关闭,避免升级后自动暴露本机信息给模型。
# en: Inject current host system information into prompts. Disabled by default to avoid exposing host data automatically after upgrades.
enabled = false
# zh: 展示操作系统、版本、release 和架构。
# en: Show operating system, version, release, and architecture.
show_os = true
# zh: 展示 Python 与 Undefined 版本。
# en: Show Python and Undefined versions.
show_runtime = true
# zh: 展示主机名。
# en: Show hostname.
show_host = true
# zh: 展示 CPU 型号与物理/逻辑核心数。
# en: Show CPU model and physical/logical core counts.
show_cpu = true
# zh: 展示当前 CPU 总使用率。
# en: Show current total CPU usage.
show_cpu_usage = true
# zh: 展示内存总量、已用量与占用率。
# en: Show memory total, used amount, and usage percentage.
show_memory = true
# zh: 展示 Swap 总量、已用量与占用率。
# en: Show swap total, used amount, and usage percentage.
show_swap = true
# zh: 展示可见磁盘分区、文件系统、容量与占用率。
# en: Show visible disk partitions, filesystem, capacity, and usage percentage.
show_disks = true
# zh: 展示非回环网卡地址与网络收发累计。涉及 IP 信息,公网或共享部署可关闭。
# en: Show non-loopback network addresses and cumulative network I/O. Disable this on public or shared deployments if IP exposure is undesirable.
show_network = true
# zh: 展示 Bot 进程 PID、启动时间、运行时长、RSS 与进程 CPU 占用。
# en: Show bot process PID, start time, uptime, RSS, and process CPU usage.
show_process = true
# zh: 展示系统启动时间与系统运行时长。
# en: Show system boot time and uptime.
show_uptime = true
# zh: 搜索服务配置。
# en: Search service config.
[search]
Expand Down
23 changes: 23 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,29 @@ Prompt caching 补充:

---

### 4.11.1 `[prompt.system_info]` Prompt 系统信息注入

| 字段 | 默认值 | 说明 |
|---|---:|---|
| `enabled` | `false` | 总开关。开启后把当前运行主机的系统信息注入主模型 Prompt;默认关闭,避免升级后自动暴露本机信息给上游模型 |
| `show_os` | `true` | 展示操作系统、版本、release 与架构 |
| `show_runtime` | `true` | 展示 Python 与 Undefined 版本 |
| `show_host` | `true` | 展示主机名 |
| `show_cpu` | `true` | 展示 CPU 型号、物理核心数与逻辑核心数 |
| `show_cpu_usage` | `true` | 展示当前 CPU 总使用率 |
| `show_memory` | `true` | 展示内存总量、已用量与占用率 |
| `show_swap` | `true` | 展示 Swap 总量、已用量与占用率 |
| `show_disks` | `true` | 展示可见磁盘分区、文件系统、容量与占用率 |
| `show_network` | `true` | 展示非回环网卡地址与网络收发累计;涉及 IP 信息,公网或共享部署可关闭 |
| `show_process` | `true` | 展示 Bot 进程 PID、启动时间、运行时长、RSS 与进程 CPU 占用 |
| `show_uptime` | `true` | 展示系统启动时间与系统运行时长 |

采集实现优先使用 `psutil` 与 Python 标准库 `platform/socket/os/time`,目标是 Windows、macOS、Linux 跨平台可用。单项采集失败时只省略该项,不会中断 Prompt 构建。该块属于动态上下文,会放在历史/记忆之后、`【当前时间】` 之前。

安全边界:不会注入 API Key、环境变量、命令行参数、完整配置文件内容、用户目录文件列表等敏感内容。主机名、网络地址、磁盘挂载点和 PID 属于运维信息,启用前请确认当前模型供应商和部署场景允许暴露这些信息。

---

### 4.12 `[search]` 搜索

| 字段 | 默认值 | 说明 |
Expand Down
2 changes: 1 addition & 1 deletion docs/message-batching.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

`res/prompts/undefined.xml`、`res/prompts/undefined_nagaagent.xml` 与 `res/IMPORTANT/each.md` 均按"当前输入批次"适配:有【连续消息说明】时整批当前 `<message>` 都属于本轮输入;没有连续说明时,当前输入批次退化为最后一条消息。防幽灵任务规则仍然生效,但它只隔离当前输入批次之外的历史消息;「催促/在吗」不等于新任务,历史同类或语义等价操作不得自动重跑(与 each.md 硬性熔断一致)。

Prompt 构建顺序按缓存命中友好设计:固定系统提示词、运行环境配置、Skills 元数据和强制规则尽量放在前面;会频繁变化的 memory / cognitive / end 摘要 / history / 当前时间 / 当前输入批次放在后面。`system_prompt_as_user=true` 时,系统块会合并进首条 user,但合并后的文本仍保留这个顺序,且当前输入批次仍在最后。
Prompt 构建顺序按缓存命中友好设计:固定系统提示词、运行环境配置、Skills 元数据和强制规则尽量放在前面;会频繁变化的 memory / cognitive / end 摘要 / history / 可选系统信息 / 当前时间 / 当前输入批次放在后面。`system_prompt_as_user=true` 时,系统块会合并进首条 user,但合并后的文本仍保留这个顺序,且当前输入批次仍在最后。

`end.memo` / `end.observations` 也按同一语义适配:当前输入批次包含多条连续消息时,短期 memo 要概括整批处理结果,认知 observations 要覆盖整批消息中有价值的新观察;这些观察不要求与 bot 相关,也不要求长期稳定,但只能来自当前输入批次。历史消息、认知记忆、侧写和最近消息参考只用于消歧,不能作为 observations 的新事实来源。后台史官收到的 `source_message` 会按时间顺序列出本批所有 `<message>`,不会只取最后一条。

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "Undefined-bot"
version = "3.6.3"
version = "3.6.4"
description = "QQ bot platform with cognitive memory architecture and multi-agent Skills, via OneBot V11."
readme = "README.md"
authors = [
Expand Down
4 changes: 2 additions & 2 deletions scripts/bump_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ def bump_project_versions(
),
(
root / "src" / "Undefined" / "__init__.py",
r'^__version__\s*=\s*"[^"]+"',
f'__version__ = "{version}"',
r'^(__version__(?:\s*:\s*str)?\s*=\s*)"[^"]+"',
rf'\g<1>"{version}"',
),
)
for path, pattern, replacement in text_targets:
Expand Down
2 changes: 1 addition & 1 deletion src/Undefined/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .skills.registry import BaseRegistry as BaseRegistry
from .skills.tools import ToolRegistry as ToolRegistry

__version__ = "3.6.3"
__version__: str = "3.6.4"

# symbol -> (module_path, attribute_name);首次访问时才 importlib 加载
_LAZY_IMPORTS: dict[str, tuple[str, str]] = {
Expand Down
23 changes: 23 additions & 0 deletions src/Undefined/ai/prompts/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import logging
import asyncio
from collections import deque
from datetime import datetime
from typing import Any, Awaitable, Callable, Literal
Expand Down Expand Up @@ -30,6 +31,7 @@
build_model_config_info,
select_system_prompt_path,
)
from Undefined.ai.prompts.system_info import build_prompt_system_info

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -520,6 +522,20 @@ async def emit_webchat_stage(stage: str, detail: Any | None = None) -> None:
# 记忆/认知/历史等上下文统一排在主 system 之后、当前消息之前
messages.extend(deferred_messages)

if self._runtime_config_getter is not None:
try:
system_info = await asyncio.to_thread(
self._build_prompt_system_info_from_runtime_config
)
if system_info:
messages.append({"role": "system", "content": system_info})
logger.debug(
"[Prompt] 已注入当前系统信息,长度=%s",
len(system_info),
)
except Exception as exc:
logger.debug("读取当前系统信息失败: %s", exc)

Comment thread
coderabbitai[bot] marked this conversation as resolved.
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
messages.append(
{
Expand All @@ -538,6 +554,13 @@ async def emit_webchat_stage(stage: str, detail: Any | None = None) -> None:
)
return messages

def _build_prompt_system_info_from_runtime_config(self) -> str:
if self._runtime_config_getter is None:
return ""
runtime_config = self._runtime_config_getter()
system_info_config = getattr(runtime_config, "prompt_system_info", None)
return build_prompt_system_info(system_info_config)

def _resolve_chat_scope(
self, extra_context: dict[str, Any] | None
) -> tuple[Literal["group", "private"], int] | None:
Expand Down
Loading
Loading