feat: 将项目从nano重命名为beaver并更新相关配置

- 将所有环境变量前缀从NANO_改为BEAVER_
- 更新README.md文档内容,包括项目介绍、组件说明和快速开始指南
- 修改.gitignore文件,添加auth-portal运行时路径排除规则
- 更新app-instance镜像标签从nano/app-instance改为beaver/app-instance
- 增强技能安全检查器,支持工具前缀白名单功能
- 添加技能草稿重新检查安全性API端点
- 扩展证据选择器,收集工具调用名称用于技能学习
- 改进技能合成器,基于实际调用的工具生成工具提示
- 优化路由超时处理机制,增加重试逻辑
- 更新后端架构文档,添加可视化入口和基础概念说明
- 实现在WebSocket消息中传递工具迭代次数信息
This commit is contained in:
2026-05-20 18:01:06 +08:00
parent 3b0af173cc
commit 9d6cde2d23
63 changed files with 4894 additions and 1596 deletions

View File

@ -4,7 +4,7 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REGISTRY_TOOL="${SCRIPT_DIR}/instance-registry.py"
IMAGE_NAME="${IMAGE_NAME:-nano/app-instance:latest}"
IMAGE_NAME="${IMAGE_NAME:-beaver/app-instance:latest}"
INSTANCES_ROOT_DEFAULT="${SCRIPT_DIR}/runtime/instances"
REGISTRY_PATH_DEFAULT="${SCRIPT_DIR}/runtime/registry/instances.json"
KNOWN_PROVIDERS=" custom anthropic openai openrouter deepseek groq zhipu dashscope vllm gemini moonshot minimax aihubmix siliconflow volcengine "
@ -25,6 +25,7 @@ MODEL="openai/gpt-5"
PROVIDER="openai"
API_KEY="${API_KEY:-}"
API_BASE="${API_BASE:-}"
SKIP_PROVIDER_CONFIG=0
AUTH_USERNAME=""
AUTH_PASSWORD=""
USERNAME=""
@ -42,22 +43,23 @@ REPLACE=0
usage() {
cat <<'EOF'
Usage:
./create-instance.sh --instance-id demo --auth-username admin --auth-password 123456 --api-key sk-xxx [options]
./create-instance.sh --instance-id demo --auth-username admin --auth-password 123456 [options]
Required:
--instance-id <id> Unique instance id.
--auth-username <name> Initial web login username.
--auth-password <password> Initial web login password.
--api-key <key> Provider API key for Boardware Genius.
Optional:
--image <name> Docker image tag. Default: nano/app-instance:latest
--image <name> Docker image tag. Default: beaver/app-instance:latest
--container-name <name> Docker container name. Default: app-instance-<slug>
--host-port <port> Host port to publish. Default: auto-pick from 20000-29999.
--public-url <url> Public URL exposed to users. Default: http://127.0.0.1:<host-port>
--provider <name> Provider key in config.json. Default: openai
--api-base <url> Optional custom provider base URL.
--api-key <key> Provider API key for Boardware Genius.
--model <name> Model name. Default: openai/gpt-5
--skip-provider-config Create the instance without model/provider/API key settings.
--authz-base-url <url> AuthZ service base URL.
--authz-outlook-mcp-url <url>
Managed Outlook MCP URL for AuthZ mode.
@ -134,6 +136,7 @@ render_config_json() {
PROVIDER="$PROVIDER" \
API_KEY="$API_KEY" \
API_BASE="$API_BASE" \
SKIP_PROVIDER_CONFIG="$SKIP_PROVIDER_CONFIG" \
AUTHZ_BASE_URL="$AUTHZ_BASE_URL" \
AUTHZ_OUTLOOK_MCP_URL="$AUTHZ_OUTLOOK_MCP_URL" \
OUTLOOK_MCP_SERVER_ID="$OUTLOOK_MCP_SERVER_ID" \
@ -151,11 +154,20 @@ target = Path(os.environ["TARGET_PATH"])
provider = os.environ["PROVIDER"]
outlook_mcp_url = os.environ["AUTHZ_OUTLOOK_MCP_URL"].strip()
outlook_server_id = os.environ["OUTLOOK_MCP_SERVER_ID"].strip() or "outlook_mcp"
skip_provider_config = os.environ["SKIP_PROVIDER_CONFIG"].strip() == "1"
provider_cfg = {"apiKey": os.environ["API_KEY"]}
api_base = os.environ["API_BASE"].strip()
if api_base:
provider_cfg["apiBase"] = api_base
providers = {}
agent_defaults = {
"workspace": "/root/.beaver/workspace",
}
if not skip_provider_config:
provider_cfg = {"apiKey": os.environ["API_KEY"]}
api_base = os.environ["API_BASE"].strip()
if api_base:
provider_cfg["apiBase"] = api_base
providers[provider] = provider_cfg
agent_defaults["provider"] = provider
agent_defaults["model"] = os.environ["MODEL"]
outlook_tool_names = [
"auth_status",
@ -193,14 +205,9 @@ if outlook_mcp_url:
data = {
"agents": {
"defaults": {
"workspace": "/root/.beaver/workspace",
"model": os.environ["MODEL"],
}
},
"providers": {
provider: provider_cfg,
"defaults": agent_defaults
},
"providers": providers,
"tools": {
"restrictToWorkspace": True,
"mcpServers": default_mcp_servers,
@ -345,6 +352,10 @@ while [[ $# -gt 0 ]]; do
MODEL="${2:-}"
shift 2
;;
--skip-provider-config)
SKIP_PROVIDER_CONFIG=1
shift
;;
--auth-username)
AUTH_USERNAME="${2:-}"
shift 2
@ -438,7 +449,9 @@ done
[[ -n "$INSTANCE_ID" ]] || die "--instance-id is required"
[[ -n "$AUTH_USERNAME" ]] || die "--auth-username is required"
[[ -n "$AUTH_PASSWORD" ]] || die "--auth-password is required"
[[ -n "$API_KEY" ]] || die "--api-key is required"
if [[ "$SKIP_PROVIDER_CONFIG" -ne 1 ]]; then
[[ -n "$API_KEY" ]] || die "--api-key is required unless --skip-provider-config is set"
fi
INSTANCE_SLUG="$(slugify "$INSTANCE_ID")"
USERNAME="${USERNAME:-$AUTH_USERNAME}"
@ -469,10 +482,12 @@ if [[ -z "$INSTANCE_HOST" ]]; then
INSTANCE_HOST="$(extract_url_host "$PUBLIC_URL")"
fi
case "$KNOWN_PROVIDERS" in
*" ${PROVIDER} "*) ;;
*) die "unsupported provider '${PROVIDER}'" ;;
esac
if [[ "$SKIP_PROVIDER_CONFIG" -ne 1 ]]; then
case "$KNOWN_PROVIDERS" in
*" ${PROVIDER} "*) ;;
*) die "unsupported provider '${PROVIDER}'" ;;
esac
fi
if [[ -n "$BACKEND_ID$CLIENT_ID$CLIENT_SECRET" ]]; then
[[ -n "$BACKEND_ID" && -n "$CLIENT_ID" && -n "$CLIENT_SECRET" ]] || die "backend identity requires --backend-id, --client-id and --client-secret together"
@ -550,9 +565,9 @@ RUN_ARGS=(
-e "APP_FRONTEND_PORT=3000"
-e "APP_BACKEND_PORT=18080"
-e "BEAVER_OUTLOOK_MCP_SERVER_ID=${OUTLOOK_MCP_SERVER_ID}"
--label "nano.instance.id=${INSTANCE_ID}"
--label "nano.instance.slug=${INSTANCE_SLUG}"
--label "nano.instance.public_url=${PUBLIC_URL}"
--label "beaver.instance.id=${INSTANCE_ID}"
--label "beaver.instance.slug=${INSTANCE_SLUG}"
--label "beaver.instance.public_url=${PUBLIC_URL}"
)
if [[ -n "$NETWORK_NAME" ]]; then