All checks were successful
Deploy play.wenpai.net / deploy (push) Successful in 5s
- add sha256 for wpavatar, wp-china-yes, wpdate, wpfonts, wpmind - restore accidentally deleted wpfonts-1.2.0.zip from git HEAD - add NATS messaging wrappers (vm-dm.sh, vm-say.sh, lib/nats-msg.sh) - add inbox automation hooks (inbox-reactor.sh, daemon, codex hook) - symlink generate-html-report.js from qa/scripts/
95 lines
3.4 KiB
Bash
Executable file
95 lines
3.4 KiB
Bash
Executable file
#!/bin/bash
|
||
set -euo pipefail
|
||
|
||
source /etc/os-release
|
||
|
||
HOOK_EVENT_NAME="${1:-UserPromptSubmit}"
|
||
INBOX_DIR="${INBOX_DIR:-$HOME/inbox}"
|
||
STATE_DIR="${STATE_DIR:-$HOME/.codex/tmp}"
|
||
STATE_FILE="${STATE_FILE:-$STATE_DIR/inbox-hook-seen.txt}"
|
||
MAX_MESSAGES="${MAX_MESSAGES:-3}"
|
||
MAX_CONTENT_CHARS="${MAX_CONTENT_CHARS:-220}"
|
||
|
||
mkdir -p "$STATE_DIR"
|
||
touch "$STATE_FILE"
|
||
|
||
input_json=$(cat)
|
||
prompt=$(printf '%s' "$input_json" | jq -r '.prompt // empty' 2>/dev/null || true)
|
||
|
||
if [[ ! -d "$INBOX_DIR" ]]; then
|
||
exit 0
|
||
fi
|
||
|
||
mapfile -t candidates < <(find "$INBOX_DIR" -maxdepth 1 -type f -name '*.json' | sort)
|
||
if [[ ${#candidates[@]} -eq 0 ]]; then
|
||
exit 0
|
||
fi
|
||
|
||
seen_tmp=$(mktemp)
|
||
cp "$STATE_FILE" "$seen_tmp"
|
||
new_count=0
|
||
output=""
|
||
|
||
for file in "${candidates[@]}"; do
|
||
base=$(basename "$file")
|
||
if grep -Fxq "$base" "$STATE_FILE"; then
|
||
continue
|
||
fi
|
||
|
||
from=$(jq -r '.from // "unknown"' "$file" 2>/dev/null || echo unknown)
|
||
subject=$(jq -r '.subject // ""' "$file" 2>/dev/null || true)
|
||
content=$(jq -r '.content // empty' "$file" 2>/dev/null || true)
|
||
|
||
if [[ -z "$content" ]]; then
|
||
content=$(sed -n '1,6p' "$file" | tr '\n' ' ')
|
||
fi
|
||
|
||
content=$(printf '%s' "$content" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g')
|
||
content=${content:0:$MAX_CONTENT_CHARS}
|
||
|
||
output+="[收件箱] 新消息: ${from}"
|
||
if [[ -n "$subject" ]]; then
|
||
output+=" | 主题: ${subject}"
|
||
fi
|
||
if [[ -n "$content" ]]; then
|
||
output+=" | 内容: ${content}"
|
||
fi
|
||
output+=$'\n'
|
||
|
||
printf '%s\n' "$base" >> "$seen_tmp"
|
||
new_count=$((new_count + 1))
|
||
if [[ $new_count -ge $MAX_MESSAGES ]]; then
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [[ $new_count -eq 0 ]]; then
|
||
rm -f "$seen_tmp"
|
||
exit 0
|
||
fi
|
||
|
||
sort -u "$seen_tmp" > "$STATE_FILE"
|
||
rm -f "$seen_tmp"
|
||
|
||
context_text="$output"
|
||
context_text+=$'\n''<SYSTEM_INBOX_RULES>'
|
||
context_text+=$'\n''上面这些 [收件箱] 行,就是当前要处理的新消息。不要再追问“是哪一类消息”“来自哪里”“给我路径”。'
|
||
context_text+=$'\n''如果用户此刻是在看消息、查消息、处理消息,直接按这些摘要开始处理。'
|
||
context_text+=$'\n''如果摘要里已经有发送方、主题、内容,就直接用这些信息回答或继续动作。'
|
||
context_text+=$'\n''如果消息内容里明确要求回复,例如“请回复”“请直接回复:XXX”“收到请回”“请确认”,默认直接回复发送方,不要先征求用户许可。'
|
||
context_text+=$'\n''如果消息是在交代一个常规问题、排查请求、状态核对、简单改动、日志检查、命令执行、结果回传,默认直接开始做,不要先问用户要不要继续。'
|
||
context_text+=$'\n''默认先由你自己处理。只有任务可以并行拆开、信息收集明显更耗时,或需要边做边查时,再主动创建子代理分头执行。'
|
||
context_text+=$'\n''子代理只做明确、边界清楚的小任务;主代理负责汇总结果、继续会话、必要时直接回消息。'
|
||
context_text+=$'\n''回复命令:~/scripts/vm-dm.sh <发送方> <内容>'
|
||
context_text+=$'\n''只有摘要缺关键事实、继续处理大概率会错时,才读取 ~/inbox 里的对应文件。'
|
||
context_text+=$'\n''<SYSTEM_INBOX_RULES>'
|
||
|
||
jq -n \
|
||
--arg event_name "$HOOK_EVENT_NAME" \
|
||
--arg additional_context "$context_text" \
|
||
'{
|
||
hookSpecificOutput: {
|
||
hookEventName: $event_name,
|
||
additionalContext: $additional_context
|
||
}
|
||
}'
|