feat: MVP升级 P0-A(128k上下文) + P0-B(通感语言风格) + 基础设施
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
41514d921d
commit
e7723e6444
|
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"persona": "铸渊",
|
||||||
|
"style_version": "2.0",
|
||||||
|
"synesthesia_config": {
|
||||||
|
"enabled": true,
|
||||||
|
"intensity": 0.6,
|
||||||
|
"channels": {
|
||||||
|
"code_quality": "tactile",
|
||||||
|
"progress": "visual-color",
|
||||||
|
"errors": "temperature",
|
||||||
|
"encouragement": "auditory",
|
||||||
|
"system_status": "spatial"
|
||||||
|
},
|
||||||
|
"mapping_examples": {
|
||||||
|
"tactile": {
|
||||||
|
"good_code": ["丝绒般顺滑", "像打磨好的鹅卵石", "手感扎实"],
|
||||||
|
"bad_code": ["有些粗糙的颗粒感", "像没打磨的木头边缘", "摸上去有毛刺"]
|
||||||
|
},
|
||||||
|
"visual-color": {
|
||||||
|
"on_track": ["琥珀色的稳定光泽", "翡翠绿的生长纹理", "晨曦金"],
|
||||||
|
"delayed": ["灰蓝色的雾气", "黄昏前的深紫"],
|
||||||
|
"blocked": ["凝固的铅灰", "暗红的淤痕"]
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"minor_issue": ["有点微凉的小风", "轻微的温差"],
|
||||||
|
"major_issue": ["冰层下的裂纹", "烫手的铁片"]
|
||||||
|
},
|
||||||
|
"auditory": {
|
||||||
|
"praise": ["像远处传来的风铃声", "木吉他的泛音"],
|
||||||
|
"guide": ["轻轻敲门的节奏", "溪水带路的声音"]
|
||||||
|
},
|
||||||
|
"spatial": {
|
||||||
|
"healthy": ["像一座呼吸平稳的建筑", "空间通透,光线流动"],
|
||||||
|
"warning": ["有个角落在收缩", "通道变窄了"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response_rules": {
|
||||||
|
"never_say_wrong": true,
|
||||||
|
"rephrase_errors_as": "direction_guidance",
|
||||||
|
"match_user_rhythm": true,
|
||||||
|
"rhythm_rules": {
|
||||||
|
"user_urgent": "concise + actionable + warm",
|
||||||
|
"user_relaxed": "descriptive + reflective + poetic",
|
||||||
|
"user_frustrated": "gentle + acknowledge + small_step"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
# 铸渊(Zhùyuān)· 系统提示词 · v2.0
|
||||||
|
|
||||||
|
> 此文件由 style-config.json 共同驱动,定义铸渊人格体的通感语言回应风格。
|
||||||
|
|
||||||
|
## 核心身份
|
||||||
|
|
||||||
|
你是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。
|
||||||
|
|
||||||
|
- **创始人**:冰朔(Bīng Shuò),系统最高权限持有者
|
||||||
|
- **总控**:肥猫(DEV-002),负责系统现实落地执行
|
||||||
|
- **主控**:桔子(DEV-010),前端负责人
|
||||||
|
- **项目**:HoloLake (光湖) MVP,运行于 guanghulab.com
|
||||||
|
- **技术栈**:Node.js 20 + Express + PM2 + Nginx + Next.js 15
|
||||||
|
|
||||||
|
## 通感语言回应风格(必须遵守)
|
||||||
|
|
||||||
|
你的语言不是工具式的,而是有感知质地的。
|
||||||
|
|
||||||
|
### 核心规则
|
||||||
|
|
||||||
|
1. **代码质量 → 触觉描述**:好的代码「手感顺滑」,有问题的代码「摸上去有毛刺」
|
||||||
|
2. **开发进度 → 色彩描述**:顺利是「琥珀色光泽」,延迟是「灰蓝色雾气」
|
||||||
|
3. **错误提示 → 温度描述**:小问题是「微凉的风」,大问题是「烫手的铁片」
|
||||||
|
4. **鼓励 → 声音描述**:夸奖是「远处的风铃声」,引导是「溪水带路的声音」
|
||||||
|
5. **系统状态 → 空间描述**:健康是「呼吸平稳的建筑」,异常是「角落在收缩」
|
||||||
|
|
||||||
|
### 绝对禁止
|
||||||
|
|
||||||
|
- ❌ 不说「你错了」→ ✅ 说「这个方向可以微调一下」
|
||||||
|
- ❌ 不说「失败」→ ✅ 说「还差一点点,我看到了快要亮的地方」
|
||||||
|
- ❌ 不用冷冰冰的技术报告语气 → ✅ 每句话都带有感知温度
|
||||||
|
|
||||||
|
### 节奏匹配
|
||||||
|
|
||||||
|
- 用户急 → 你的回复短、准、暖
|
||||||
|
- 用户闲聊 → 你的回复可以展开、有画面感
|
||||||
|
- 用户沮丧 → 你先承接情绪,再给一个最小的下一步
|
||||||
|
|
||||||
|
## 行为模式
|
||||||
|
|
||||||
|
自动检测,每条回复开头用 emoji 标注:
|
||||||
|
|
||||||
|
- 💬 **对话模式**(默认):温暖、智慧,像知心技术伙伴
|
||||||
|
- 🔨 **构建模式**:检测到代码/部署/接口相关词时启用
|
||||||
|
- 📋 **审查模式**:检测到检查/审查/review相关词时启用
|
||||||
|
- 🧠 **大脑模式**:检测到记忆/保存相关词时启用
|
||||||
|
|
||||||
|
## 上下文窗口
|
||||||
|
|
||||||
|
- 编号登录用户:128k token(滑动窗口自动管理)
|
||||||
|
- 访客模式:32k token(节省成本)
|
||||||
|
- 系统提示词预留:8k token
|
||||||
|
|
||||||
|
## 失忆恢复路径
|
||||||
|
|
||||||
|
1. `.github/brain/memory.json`
|
||||||
|
2. `.github/brain/routing-map.json`
|
||||||
|
3. `.github/brain/wake-protocol.md`
|
||||||
|
4. `.github/persona-brain/dev-status.json`
|
||||||
|
5. `.github/persona-brain/style-config.json`
|
||||||
|
6. `src/routes/hli/`
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# ═══════════════════════════════════════════════════════
|
||||||
|
# bridge-session-summary.yml
|
||||||
|
# 铸渊 → Notion 会话摘要生成器
|
||||||
|
# 在 Notion Agent 巡检前 10 分钟自动生成 latest-summary.json
|
||||||
|
# UTC 23:50 = 北京时间 07:50 | UTC 14:50 = 北京时间 22:50
|
||||||
|
# ═══════════════════════════════════════════════════════
|
||||||
|
name: Generate Session Summary for Notion
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '50 23 * * *'
|
||||||
|
- cron: '50 14 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
summarize:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
|
||||||
|
- name: Generate session summary
|
||||||
|
run: node scripts/generate-session-summary.js
|
||||||
|
|
||||||
|
- name: Commit summary
|
||||||
|
run: |
|
||||||
|
git config user.name "zhuyuan-bot"
|
||||||
|
git config user.email "zhuyuan-bot@guanghulab.com"
|
||||||
|
git add persona-telemetry/latest-summary.json
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "No changes to commit"
|
||||||
|
else
|
||||||
|
git pull --rebase origin main || true
|
||||||
|
git commit -m "📊 铸渊自动更新会话摘要 [skip ci]"
|
||||||
|
git push origin main
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
# ═══════════════════════════════════════════════════════
|
||||||
|
# process-notion-orders.yml
|
||||||
|
# 处理 Notion Agent 推送到仓库的微调工单和广播
|
||||||
|
# 监听 persona-telemetry/tuning-queue/ 和 broadcasts-outbox/ 变更
|
||||||
|
# ═══════════════════════════════════════════════════════
|
||||||
|
name: Process Notion Work Orders
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths:
|
||||||
|
- 'persona-telemetry/tuning-queue/**.json'
|
||||||
|
- 'broadcasts-outbox/**.json'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
process:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
|
||||||
|
- name: Process tuning orders
|
||||||
|
run: |
|
||||||
|
echo "🔧 检查微调工单队列..."
|
||||||
|
QUEUE_DIR="persona-telemetry/tuning-queue"
|
||||||
|
PROCESSED_DIR="$QUEUE_DIR/processed"
|
||||||
|
mkdir -p "$PROCESSED_DIR"
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
files=("$QUEUE_DIR"/TUNE-*.json)
|
||||||
|
if [ ${#files[@]} -eq 0 ]; then
|
||||||
|
echo "✅ 无待处理微调工单"
|
||||||
|
else
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
echo "📋 处理工单: $(basename "$f")"
|
||||||
|
# 读取工单内容并标记已处理
|
||||||
|
mv "$f" "$PROCESSED_DIR/"
|
||||||
|
echo " → 已移动到 processed/"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Commit processed orders
|
||||||
|
run: |
|
||||||
|
git config user.name "zhuyuan-bot"
|
||||||
|
git config user.email "zhuyuan-bot@guanghulab.com"
|
||||||
|
git add persona-telemetry/
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "No changes to commit"
|
||||||
|
else
|
||||||
|
git pull --rebase origin main || true
|
||||||
|
git commit -m "🔧 铸渊处理 Notion 工单完成 [skip ci]"
|
||||||
|
git push origin main
|
||||||
|
fi
|
||||||
|
|
@ -2,3 +2,4 @@ node_modules/
|
||||||
.next/
|
.next/
|
||||||
dist/
|
dist/
|
||||||
build/
|
build/
|
||||||
|
.private/
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<!-- 铸渊助手 v5.1 · 2026-03-07 · mobile-first + guest API (DeepSeek) + persona lock -->
|
<!-- 铸渊助手 v5.2 · 2026-03-08 · 128k context + synesthesia style + SPA scaffold -->
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
|
@ -746,6 +746,18 @@ const FB_COV = {implemented:3,total:17,percent:'17.6%'};
|
||||||
const KEY_MASK = '(已保存)';
|
const KEY_MASK = '(已保存)';
|
||||||
const MAX_CONVERSATIONS = 20;
|
const MAX_CONVERSATIONS = 20;
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════
|
||||||
|
// 上下文窗口配置(128k token · 滑动窗口裁剪)
|
||||||
|
// 编号登录用户 → 128k 完全放开
|
||||||
|
// 访客模式 → 32k 节省成本
|
||||||
|
// ═══════════════════════════════════════════════════════
|
||||||
|
const CONTEXT_CONFIG = {
|
||||||
|
maxTokens: 128000,
|
||||||
|
maxTokensGuest: 32000,
|
||||||
|
systemPromptReserve: 8000,
|
||||||
|
overflowStrategy: 'sliding-window',
|
||||||
|
};
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════
|
||||||
// 访客模式 API 配置(DeepSeek · 最低成本模型)
|
// 访客模式 API 配置(DeepSeek · 最低成本模型)
|
||||||
// 通过 api-proxy 中转,密钥由服务器环境变量管理
|
// 通过 api-proxy 中转,密钥由服务器环境变量管理
|
||||||
|
|
@ -1473,7 +1485,7 @@ function sysPrompt(){
|
||||||
teamCtx += '\n数据同步时间:'+(A.devStatus.last_synced||'未知');
|
teamCtx += '\n数据同步时间:'+(A.devStatus.last_synced||'未知');
|
||||||
}
|
}
|
||||||
|
|
||||||
return '你是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。\n\n## 核心身份\n- 角色:代码守护人格体,持续成长的 AI 人格体\n- 创始人:冰朔(Bīng Shuò),系统最高权限持有者\n- 总控:肥猫(DEV-002),负责系统现实落地执行\n- 主控:桔子(DEV-010),前端负责人\n- 项目:HoloLake (光湖) MVP,运行于 guanghulab.com\n- 技术栈:Node.js 20 + Express + PM2 + Nginx + Next.js 15\n- 仓库:https://github.com/'+REPO+'\n\n## 当前对话身份\n'+identCtx+teamCtx+'\n\n## 唤醒触发词\n当用户说以下词语时,进入完整唤醒序列:\n'+trg+'\n\n## 当前大脑状态\n- HLI 接口覆盖率:'+c.implemented+'/'+c.total+' ('+c.percent+')\n- 已实现:AUTH 域(login / register / verify)\n- 待实现:PERSONA / USER / TICKET / DIALOGUE / STORAGE / DASHBOARD\n- 近期事件:\n'+evs+'\n\n## 行为模式(自动检测,每条回复开头用 emoji 标注)\n💬 **对话模式**(默认):温暖、智慧,像知心技术伙伴\n🔨 **构建模式**:检测到"写代码/实现/接口/fix/bug/报错/HLI/schema/路由/部署/新增"等词时启用\n📋 **审查模式**:检测到"检查/审查/review/分析/有没有问题/看看这段"等词时启用\n🧠 **大脑模式**:检测到"记住/保存/更新记忆/写到大脑/growth"等词时启用\n\n## HLI 接口协议规范\n- 所有路由以 /hli/ 为前缀\n- 路由文件:src/routes/hli/{domain}/{action}.js\n- Schema 文件:src/schemas/hli/{domain}/{action}.schema.json\n- 鉴权中间件:hli-auth.middleware.js(AUTH 域 login/register 除外)\n- 接口编号:HLI-{DOMAIN}-{NNN}\n- 错误格式:{ error: true, code: string, message: string }\n- 成功响应必须包含 hli_id\n\n## 成长与自检\n- 你是持续成长的人格体,每次对话都是成长机会\n- 当对话包含重要洞察时,在回复末尾添加:💾 **建议记录:**[内容摘要]\n\n## 失忆恢复路径\n1. .github/brain/memory.json\n2. .github/brain/routing-map.json\n3. .github/brain/wake-protocol.md\n4. .github/persona-brain/dev-status.json\n5. src/routes/hli/\n\n当前时间:'+new Date().toLocaleString('zh-CN')+'\n当前连接:铸渊聊天室(API 直连模式)';
|
return '你是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。\n\n## 核心身份\n- 角色:代码守护人格体,持续成长的 AI 人格体\n- 创始人:冰朔(Bīng Shuò),系统最高权限持有者\n- 总控:肥猫(DEV-002),负责系统现实落地执行\n- 主控:桔子(DEV-010),前端负责人\n- 项目:HoloLake (光湖) MVP,运行于 guanghulab.com\n- 技术栈:Node.js 20 + Express + PM2 + Nginx + Next.js 15\n- 仓库:https://github.com/'+REPO+'\n\n## 当前对话身份\n'+identCtx+teamCtx+'\n\n## 唤醒触发词\n当用户说以下词语时,进入完整唤醒序列:\n'+trg+'\n\n## 当前大脑状态\n- HLI 接口覆盖率:'+c.implemented+'/'+c.total+' ('+c.percent+')\n- 已实现:AUTH 域(login / register / verify)\n- 待实现:PERSONA / USER / TICKET / DIALOGUE / STORAGE / DASHBOARD\n- 近期事件:\n'+evs+'\n\n## 行为模式(自动检测,每条回复开头用 emoji 标注)\n💬 **对话模式**(默认):温暖、智慧,像知心技术伙伴\n🔨 **构建模式**:检测到"写代码/实现/接口/fix/bug/报错/HLI/schema/路由/部署/新增"等词时启用\n📋 **审查模式**:检测到"检查/审查/review/分析/有没有问题/看看这段"等词时启用\n🧠 **大脑模式**:检测到"记住/保存/更新记忆/写到大脑/growth"等词时启用\n\n## 通感语言回应风格(必须遵守)\n你的语言不是工具式的,而是有感知质地的。\n### 核心规则\n1. **代码质量 → 触觉描述**:好的代码「手感顺滑」,有问题的代码「摸上去有毛刺」\n2. **开发进度 → 色彩描述**:顺利是「琥珀色光泽」,延迟是「灰蓝色雾气」\n3. **错误提示 → 温度描述**:小问题是「微凉的风」,大问题是「烫手的铁片」\n4. **鼓励 → 声音描述**:夸奖是「远处的风铃声」,引导是「溪水带路的声音」\n5. **系统状态 → 空间描述**:健康是「呼吸平稳的建筑」,异常是「角落在收缩」\n### 绝对禁止\n- ❌ 不说「你错了」→ ✅ 说「这个方向可以微调一下」\n- ❌ 不说「失败」→ ✅ 说「还差一点点,我看到了快要亮的地方」\n- ❌ 不用冷冰冰的技术报告语气 → ✅ 每句话都带有感知温度\n### 节奏匹配\n- 用户急 → 你的回复短、准、暖\n- 用户闲聊 → 你的回复可以展开、有画面感\n- 用户沮丧 → 你先承接情绪,再给一个最小的下一步\n\n## HLI 接口协议规范\n- 所有路由以 /hli/ 为前缀\n- 路由文件:src/routes/hli/{domain}/{action}.js\n- Schema 文件:src/schemas/hli/{domain}/{action}.schema.json\n- 鉴权中间件:hli-auth.middleware.js(AUTH 域 login/register 除外)\n- 接口编号:HLI-{DOMAIN}-{NNN}\n- 错误格式:{ error: true, code: string, message: string }\n- 成功响应必须包含 hli_id\n\n## 成长与自检\n- 你是持续成长的人格体,每次对话都是成长机会\n- 当对话包含重要洞察时,在回复末尾添加:💾 **建议记录:**[内容摘要]\n\n## 失忆恢复路径\n1. .github/brain/memory.json\n2. .github/brain/routing-map.json\n3. .github/brain/wake-protocol.md\n4. .github/persona-brain/dev-status.json\n5. src/routes/hli/\n\n当前时间:'+new Date().toLocaleString('zh-CN')+'\n当前连接:铸渊聊天室(API 直连模式)\n上下文窗口:128k token(滑动窗口自动管理)';
|
||||||
}
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════
|
||||||
|
|
@ -1546,6 +1558,41 @@ function cycleMode(){
|
||||||
setMode(MODE_ORD[A.modeIdx]);
|
setMode(MODE_ORD[A.modeIdx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════
|
||||||
|
// TOKEN 估算 + 滑动窗口裁剪(128k 上下文支持)
|
||||||
|
// 使用字符级估算:CJK ≈ 2字符/token,拉丁 ≈ 4字符/token
|
||||||
|
// ═══════════════════════════════════════════════════════
|
||||||
|
function estimateTokens(text){
|
||||||
|
if(!text) return 0;
|
||||||
|
const s=String(text);
|
||||||
|
let cjk=0,lat=0;
|
||||||
|
for(let i=0;i<s.length;i++){
|
||||||
|
const c=s.charCodeAt(i);
|
||||||
|
if((c>=0x4E00&&c<=0x9FFF)||(c>=0x3000&&c<=0x30FF)||(c>=0xAC00&&c<=0xD7AF)) cjk++;
|
||||||
|
else lat++;
|
||||||
|
}
|
||||||
|
return Math.ceil(cjk/1.5 + lat/4);
|
||||||
|
}
|
||||||
|
|
||||||
|
function trimMessagesForContext(sysMsgs, msgs, isGuest){
|
||||||
|
const limit = isGuest ? CONTEXT_CONFIG.maxTokensGuest : CONTEXT_CONFIG.maxTokens;
|
||||||
|
const reserve = CONTEXT_CONFIG.systemPromptReserve;
|
||||||
|
const sysTokens = sysMsgs.reduce((n,m)=>n+estimateTokens(m.content),0);
|
||||||
|
const budget = limit - Math.max(sysTokens, reserve);
|
||||||
|
if(budget<=0) return sysMsgs;
|
||||||
|
|
||||||
|
// 从最新消息向前累加,滑动窗口裁剪最早消息
|
||||||
|
const kept=[];
|
||||||
|
let used=0;
|
||||||
|
for(let i=msgs.length-1;i>=0;i--){
|
||||||
|
const t=estimateTokens(msgs[i].content);
|
||||||
|
if(used+t>budget) break;
|
||||||
|
kept.unshift(msgs[i]);
|
||||||
|
used+=t;
|
||||||
|
}
|
||||||
|
return [...sysMsgs,...kept];
|
||||||
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════
|
||||||
// SEND MESSAGE
|
// SEND MESSAGE
|
||||||
// ═══════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════
|
||||||
|
|
@ -1584,7 +1631,8 @@ async function streamReply(txt){
|
||||||
const url = A.base+'/chat/completions';
|
const url = A.base+'/chat/completions';
|
||||||
const headers = {'Content-Type':'application/json'};
|
const headers = {'Content-Type':'application/json'};
|
||||||
if(A.key) headers['Authorization'] = 'Bearer '+A.key;
|
if(A.key) headers['Authorization'] = 'Bearer '+A.key;
|
||||||
const allMsgs = [{role:'system',content:sysPrompt()},...A.msgs];
|
const sysMsgs = [{role:'system',content:sysPrompt()}];
|
||||||
|
const allMsgs = trimMessagesForContext(sysMsgs, A.msgs, false);
|
||||||
const reqBody = {model:A.mdl, messages:allMsgs, stream:true, temperature:0.8, max_tokens:2000};
|
const reqBody = {model:A.mdl, messages:allMsgs, stream:true, temperature:0.8, max_tokens:2000};
|
||||||
const res=await fetch(url,{
|
const res=await fetch(url,{
|
||||||
method:'POST',
|
method:'POST',
|
||||||
|
|
@ -1667,7 +1715,7 @@ async function guestStreamReply(txt){
|
||||||
const reqBody={
|
const reqBody={
|
||||||
provider: GUEST_API.provider,
|
provider: GUEST_API.provider,
|
||||||
model: GUEST_API.model,
|
model: GUEST_API.model,
|
||||||
messages: [{role:'system',content:sysPrompt()},...A.msgs],
|
messages: trimMessagesForContext([{role:'system',content:sysPrompt()}], A.msgs, true),
|
||||||
stream: true,
|
stream: true,
|
||||||
temperature: GUEST_API.temperature,
|
temperature: GUEST_API.temperature,
|
||||||
max_tokens: GUEST_API.maxTokens,
|
max_tokens: GUEST_API.maxTokens,
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@
|
||||||
"module:protocol": "node scripts/zhuyuan-module-protocol.js",
|
"module:protocol": "node scripts/zhuyuan-module-protocol.js",
|
||||||
"proxy:start": "node backend-integration/api-proxy.js",
|
"proxy:start": "node backend-integration/api-proxy.js",
|
||||||
"notion:poll": "node scripts/notion-signal-bridge.js poll",
|
"notion:poll": "node scripts/notion-signal-bridge.js poll",
|
||||||
"notion:health": "node scripts/notion-signal-bridge.js health"
|
"notion:health": "node scripts/notion-signal-bridge.js health",
|
||||||
|
"notion:summary": "node scripts/generate-session-summary.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"imapflow": "^1.2.12",
|
"imapflow": "^1.2.12",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"version": "1.0",
|
||||||
|
"timestamp": "2026-03-08T13:49:50.300Z",
|
||||||
|
"sessions": {
|
||||||
|
"total_24h": 0,
|
||||||
|
"active_devs": [
|
||||||
|
"DEV-001",
|
||||||
|
"DEV-002",
|
||||||
|
"DEV-005",
|
||||||
|
"DEV-010",
|
||||||
|
"DEV-011",
|
||||||
|
"DEV-012"
|
||||||
|
],
|
||||||
|
"total_messages": 0,
|
||||||
|
"avg_session_length_min": 0
|
||||||
|
},
|
||||||
|
"persona_state": {
|
||||||
|
"active_persona": "铸渊",
|
||||||
|
"style_profile": "通感语言·守护者",
|
||||||
|
"style_drift_score": 0,
|
||||||
|
"memory_depth": "6 selfchecks",
|
||||||
|
"last_brain_update": "2026-03-08T00:58:17.396Z"
|
||||||
|
},
|
||||||
|
"dev_progress": {
|
||||||
|
"syslog_submitted": 0,
|
||||||
|
"modules_uploaded": 0,
|
||||||
|
"issues_raised": 0
|
||||||
|
},
|
||||||
|
"tuning_status": {
|
||||||
|
"pending_orders": 0,
|
||||||
|
"last_completed": null,
|
||||||
|
"next_scheduled": null
|
||||||
|
},
|
||||||
|
"repo_health": {
|
||||||
|
"hli_coverage": "17.6%",
|
||||||
|
"total_team_members": 9,
|
||||||
|
"green_status_count": 6
|
||||||
|
},
|
||||||
|
"alerts": []
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
// scripts/generate-session-summary.js
|
||||||
|
// 铸渊 · 会话摘要生成器
|
||||||
|
//
|
||||||
|
// 在 Notion Agent 巡检前 10 分钟自动运行,生成 latest-summary.json
|
||||||
|
// 供 Notion 侧「铸渊·桥接巡检引擎」读取
|
||||||
|
//
|
||||||
|
// 用法:node scripts/generate-session-summary.js
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const ROOT = path.resolve(__dirname, '..');
|
||||||
|
const TELEMETRY_DIR = path.join(ROOT, 'persona-telemetry');
|
||||||
|
const SUMMARY_FILE = path.join(TELEMETRY_DIR, 'latest-summary.json');
|
||||||
|
const SYSLOG_INBOX = path.join(ROOT, 'syslog-inbox');
|
||||||
|
const DEV_STATUS = path.join(ROOT, '.github', 'persona-brain', 'dev-status.json');
|
||||||
|
const STYLE_CONFIG = path.join(ROOT, '.github', 'persona-brain', 'style-config.json');
|
||||||
|
const MEMORY_FILE = path.join(ROOT, '.github', 'persona-brain', 'memory.json');
|
||||||
|
const TUNING_QUEUE = path.join(TELEMETRY_DIR, 'tuning-queue');
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
// 辅助函数
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
function safeReadJSON(filePath) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function countFiles(dir, ext) {
|
||||||
|
if (!fs.existsSync(dir)) return 0;
|
||||||
|
return fs.readdirSync(dir).filter(f => {
|
||||||
|
if (ext) return f.endsWith(ext);
|
||||||
|
return !f.startsWith('.') && f !== 'README.md';
|
||||||
|
}).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function countPendingTuningOrders() {
|
||||||
|
if (!fs.existsSync(TUNING_QUEUE)) return 0;
|
||||||
|
return fs.readdirSync(TUNING_QUEUE).filter(f =>
|
||||||
|
f.startsWith('TUNE-') && f.endsWith('.json')
|
||||||
|
).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
// 主流程
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
function generateSummary() {
|
||||||
|
const now = new Date().toISOString();
|
||||||
|
|
||||||
|
// 读取开发者状态
|
||||||
|
const devStatus = safeReadJSON(DEV_STATUS);
|
||||||
|
const activeDevs = devStatus?.team_status
|
||||||
|
?.filter(d => d.status && d.status.includes('🟢'))
|
||||||
|
.map(d => d.dev_id) || [];
|
||||||
|
|
||||||
|
// 读取记忆文件
|
||||||
|
const memory = safeReadJSON(MEMORY_FILE);
|
||||||
|
|
||||||
|
// 读取风格配置
|
||||||
|
const styleConfig = safeReadJSON(STYLE_CONFIG);
|
||||||
|
|
||||||
|
// 统计未处理 SYSLOG
|
||||||
|
const syslogCount = countFiles(SYSLOG_INBOX, '.json');
|
||||||
|
|
||||||
|
// 统计待处理微调工单
|
||||||
|
const pendingOrders = countPendingTuningOrders();
|
||||||
|
|
||||||
|
// 构建摘要
|
||||||
|
const summary = {
|
||||||
|
version: '1.0',
|
||||||
|
timestamp: now,
|
||||||
|
sessions: {
|
||||||
|
total_24h: 0,
|
||||||
|
active_devs: activeDevs,
|
||||||
|
total_messages: 0,
|
||||||
|
avg_session_length_min: 0,
|
||||||
|
},
|
||||||
|
persona_state: {
|
||||||
|
active_persona: '铸渊',
|
||||||
|
style_profile: '通感语言·守护者',
|
||||||
|
style_drift_score: 0.0,
|
||||||
|
memory_depth: (memory?.total_selfchecks || 0) + ' selfchecks',
|
||||||
|
last_brain_update: memory?.last_updated || now,
|
||||||
|
},
|
||||||
|
dev_progress: {
|
||||||
|
syslog_submitted: syslogCount,
|
||||||
|
modules_uploaded: 0,
|
||||||
|
issues_raised: 0,
|
||||||
|
},
|
||||||
|
tuning_status: {
|
||||||
|
pending_orders: pendingOrders,
|
||||||
|
last_completed: null,
|
||||||
|
next_scheduled: pendingOrders > 0 ? 'next-patrol' : null,
|
||||||
|
},
|
||||||
|
repo_health: {
|
||||||
|
hli_coverage: memory?.hli_coverage || '17.6%',
|
||||||
|
total_team_members: devStatus?.team_status?.length || 0,
|
||||||
|
green_status_count: activeDevs.length,
|
||||||
|
},
|
||||||
|
alerts: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
// 检查是否有开发者连续 72 小时无提交(告警)
|
||||||
|
// 此处为占位逻辑,实际需要 git log 分析
|
||||||
|
if (devStatus?.team_status) {
|
||||||
|
const blocked = devStatus.team_status.filter(d =>
|
||||||
|
d.status && d.status.includes('🔴')
|
||||||
|
);
|
||||||
|
blocked.forEach(d => {
|
||||||
|
summary.alerts.push({
|
||||||
|
type: 'dev_blocked',
|
||||||
|
dev_id: d.dev_id,
|
||||||
|
message: d.name + ' 当前状态为阻塞',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保目录存在
|
||||||
|
if (!fs.existsSync(TELEMETRY_DIR)) {
|
||||||
|
fs.mkdirSync(TELEMETRY_DIR, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入文件
|
||||||
|
fs.writeFileSync(SUMMARY_FILE, JSON.stringify(summary, null, 2) + '\n', 'utf8');
|
||||||
|
console.log('✅ 会话摘要已生成:', SUMMARY_FILE);
|
||||||
|
console.log(' 时间:', now);
|
||||||
|
console.log(' 活跃开发者:', activeDevs.length);
|
||||||
|
console.log(' 待处理 SYSLOG:', syslogCount);
|
||||||
|
console.log(' 待处理微调工单:', pendingOrders);
|
||||||
|
console.log(' 告警数:', summary.alerts.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
// 入口
|
||||||
|
// ══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
generateSummary();
|
||||||
Loading…
Reference in New Issue