Skip to content

Commit f4a0d60

Browse files
authored
Merge pull request #12 from youyli03/script/send-prompt-by-script
script: add send-prompt.sh to send prompt to clawapp via proxy
2 parents 56ea920 + b626be0 commit f4a0d60

1 file changed

Lines changed: 167 additions & 0 deletions

File tree

send-prompt.sh

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
#!/usr/bin/env bash
2+
# send-prompt.sh — 向 OpenClaw 发送 prompt(fire and forget)
3+
#
4+
# 用法:
5+
# ./send-prompt.sh "你好,帮我写一首诗"
6+
# ./send-prompt.sh --session agent:main:main "帮我写代码"
7+
# ./send-prompt.sh --port 4096 "hello"
8+
# ./send-prompt.sh --file /tmp/task.txt
9+
# ./send-prompt.sh --url http://192.168.1.10:4096 --token abc "hello"
10+
# echo "从stdin读取" | ./send-prompt.sh -
11+
#
12+
# 依赖: bash, curl, python3(均为系统内置,无需额外安装)
13+
#
14+
# 环境变量:
15+
# PROXY_URL 代理地址,默认读 server/.env 中 PROXY_PORT
16+
# PROXY_TOKEN 认证 token
17+
18+
set -euo pipefail
19+
20+
# ==================== 读取 server/.env ====================
21+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22+
ENV_FILE="$SCRIPT_DIR/server/.env"
23+
24+
load_env() {
25+
if [[ -f "$ENV_FILE" ]]; then
26+
while IFS='=' read -r key val; do
27+
[[ "$key" =~ ^[A-Z0-9_]+$ ]] || continue
28+
val="${val%\"}"; val="${val#\"}"; val="${val%\'}"; val="${val#\'}"
29+
eval "ENV_${key}='${val}'"
30+
done < <(grep -E '^[A-Z0-9_]+=' "$ENV_FILE")
31+
fi
32+
}
33+
load_env
34+
35+
# ==================== 默认配置 ====================
36+
PROXY_PORT="${ENV_PROXY_PORT:-3210}"
37+
URL="${PROXY_URL:-${ENV_PROXY_URL:-}}"
38+
TOKEN="${PROXY_TOKEN:-${ENV_PROXY_TOKEN:-}}"
39+
SESSION=""
40+
FILE=""
41+
VERBOSE=false
42+
PROMPT=""
43+
44+
# ==================== 参数解析 ====================
45+
usage() {
46+
cat <<EOF
47+
用法: $(basename "$0") [选项] "<prompt>" | -
48+
49+
选项:
50+
--url <url> 代理地址 (默认: http://localhost:<port>)
51+
--port <port> 端口号 (默认: ${PROXY_PORT})
52+
--token <token> 认证 token
53+
--session <key> 指定 sessionKey (默认使用服务端 main session)
54+
--file <path> 从文件读取 prompt 内容
55+
--verbose / -v 显示调试信息
56+
- 从 stdin 读取 prompt
57+
--help 显示帮助
58+
EOF
59+
exit 0
60+
}
61+
62+
while [[ $# -gt 0 ]]; do
63+
case "$1" in
64+
--url) URL="$2"; shift 2 ;;
65+
--port) PROXY_PORT="$2"; shift 2 ;;
66+
--token) TOKEN="$2"; shift 2 ;;
67+
--session) SESSION="$2"; shift 2 ;;
68+
--file) FILE="$2"; shift 2 ;;
69+
--verbose|-v) VERBOSE=true; shift ;;
70+
--help|-h) usage ;;
71+
-) PROMPT="$(cat /dev/stdin)"; shift ;;
72+
--*) echo "未知选项: $1" >&2; exit 1 ;;
73+
*) PROMPT="${PROMPT:+${PROMPT}$'\n'}$1"; shift ;;
74+
esac
75+
done
76+
77+
# --port 生效(--url 未指定时才用)
78+
[[ -z "$URL" ]] && URL="http://localhost:${PROXY_PORT}"
79+
80+
dbg() { $VERBOSE && echo "[dbg] $*" >&2 || true; }
81+
82+
# ==================== 前置校验 ====================
83+
# --file 优先
84+
if [[ -n "$FILE" ]]; then
85+
[[ -f "$FILE" ]] || { echo "错误:文件不存在: $FILE" >&2; exit 1; }
86+
PROMPT="$(cat "$FILE")"
87+
fi
88+
89+
# stdin 模式
90+
if [[ -z "$PROMPT" && ! -t 0 ]]; then
91+
PROMPT="$(cat /dev/stdin)"
92+
fi
93+
94+
if [[ -z "$PROMPT" ]]; then
95+
echo "错误:缺少 prompt。用法: $(basename "$0") \"你的问题\"" >&2
96+
exit 1
97+
fi
98+
99+
if [[ -z "$TOKEN" ]]; then
100+
echo "错误:未设置 PROXY_TOKEN,请在 server/.env 中配置或用 --token 传入" >&2
101+
exit 1
102+
fi
103+
104+
# ==================== 工具函数 ====================
105+
json_post() {
106+
curl -sf -X POST "$1" \
107+
-H 'Content-Type: application/json' \
108+
--max-time 30 \
109+
-d "$2"
110+
}
111+
112+
json_field() {
113+
python3 -c "
114+
import sys, json
115+
d = json.loads(sys.argv[1])
116+
for k in sys.argv[2].split('.'):
117+
d = d[k]
118+
print(d)
119+
" "$1" "$2"
120+
}
121+
122+
# ==================== 主流程 ====================
123+
124+
# 1. 建立会话
125+
dbg "连接 $URL ..."
126+
CONN=$(json_post "$URL/api/connect" "{\"token\":\"$TOKEN\"}") || {
127+
echo "连接失败:服务不可达 $URL" >&2; exit 1
128+
}
129+
130+
if [[ "$(json_field "$CONN" "ok")" != "True" ]]; then
131+
echo "连接失败:$(json_field "$CONN" "error" 2>/dev/null || echo "未知错误")" >&2; exit 1
132+
fi
133+
134+
SID=$(json_field "$CONN" "sid")
135+
DEFAULT_SESSION=$(json_field "$CONN" "sessionKey")
136+
SESSION_KEY="${SESSION:-$DEFAULT_SESSION}"
137+
dbg "已连接 sid=$SID sessionKey=$SESSION_KEY"
138+
139+
# 断开会话(退出时清理)
140+
trap 'json_post "$URL/api/disconnect" "{\"sid\":\"$SID\"}" >/dev/null 2>&1 || true' EXIT INT TERM
141+
142+
# 2. 发送 prompt
143+
SEND_BODY=$(python3 -c "
144+
import json, sys, uuid
145+
print(json.dumps({
146+
'sid': sys.argv[1],
147+
'method': 'chat.send',
148+
'params': {
149+
'sessionKey': sys.argv[2],
150+
'message': sys.argv[3],
151+
'deliver': False,
152+
'idempotencyKey': str(uuid.uuid4()),
153+
}
154+
}))
155+
" "$SID" "$SESSION_KEY" "$PROMPT")
156+
157+
dbg "发送 prompt..."
158+
SEND_RESP=$(json_post "$URL/api/send" "$SEND_BODY") || {
159+
echo "发送失败:请求出错" >&2; exit 1
160+
}
161+
162+
if [[ "$(json_field "$SEND_RESP" "ok")" != "True" ]]; then
163+
echo "发送失败:$(json_field "$SEND_RESP" "error" 2>/dev/null || echo "未知错误")" >&2; exit 1
164+
fi
165+
166+
echo "已发送"
167+
dbg "chat.send ok,任务已提交,退出"

0 commit comments

Comments
 (0)